parsl 2024.3.11__py3-none-any.whl → 2025.1.13__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 (369) hide show
  1. parsl/__init__.py +9 -10
  2. parsl/addresses.py +29 -7
  3. parsl/app/app.py +7 -8
  4. parsl/app/bash.py +15 -8
  5. parsl/app/errors.py +10 -13
  6. parsl/app/futures.py +8 -10
  7. parsl/app/python.py +2 -1
  8. parsl/benchmark/perf.py +2 -1
  9. parsl/concurrent/__init__.py +2 -2
  10. parsl/config.py +57 -10
  11. parsl/configs/ASPIRE1.py +6 -5
  12. parsl/configs/Azure.py +9 -8
  13. parsl/configs/bridges.py +6 -4
  14. parsl/configs/cc_in2p3.py +3 -3
  15. parsl/configs/ec2.py +3 -1
  16. parsl/configs/expanse.py +4 -3
  17. parsl/configs/frontera.py +3 -4
  18. parsl/configs/htex_local.py +3 -4
  19. parsl/configs/illinoiscluster.py +3 -1
  20. parsl/configs/improv.py +34 -0
  21. parsl/configs/kubernetes.py +4 -3
  22. parsl/configs/local_threads.py +5 -1
  23. parsl/configs/midway.py +5 -3
  24. parsl/configs/osg.py +4 -2
  25. parsl/configs/polaris.py +4 -2
  26. parsl/configs/stampede2.py +6 -5
  27. parsl/configs/summit.py +3 -3
  28. parsl/configs/toss3_llnl.py +4 -3
  29. parsl/configs/vineex_local.py +6 -4
  30. parsl/configs/wqex_local.py +5 -3
  31. parsl/curvezmq.py +4 -0
  32. parsl/data_provider/data_manager.py +4 -3
  33. parsl/data_provider/file_noop.py +1 -2
  34. parsl/data_provider/files.py +3 -3
  35. parsl/data_provider/ftp.py +1 -3
  36. parsl/data_provider/globus.py +7 -6
  37. parsl/data_provider/http.py +2 -2
  38. parsl/data_provider/rsync.py +1 -1
  39. parsl/data_provider/staging.py +2 -2
  40. parsl/data_provider/zip.py +135 -0
  41. parsl/dataflow/dependency_resolvers.py +115 -0
  42. parsl/dataflow/dflow.py +262 -224
  43. parsl/dataflow/errors.py +3 -5
  44. parsl/dataflow/futures.py +27 -14
  45. parsl/dataflow/memoization.py +5 -5
  46. parsl/dataflow/rundirs.py +5 -6
  47. parsl/dataflow/taskrecord.py +4 -5
  48. parsl/executors/__init__.py +4 -2
  49. parsl/executors/base.py +45 -15
  50. parsl/executors/errors.py +13 -0
  51. parsl/executors/execute_task.py +37 -0
  52. parsl/executors/flux/execute_parsl_task.py +3 -3
  53. parsl/executors/flux/executor.py +18 -19
  54. parsl/executors/flux/flux_instance_manager.py +26 -27
  55. parsl/executors/high_throughput/errors.py +43 -3
  56. parsl/executors/high_throughput/executor.py +316 -282
  57. parsl/executors/high_throughput/interchange.py +158 -167
  58. parsl/executors/high_throughput/manager_record.py +5 -0
  59. parsl/executors/high_throughput/manager_selector.py +55 -0
  60. parsl/executors/high_throughput/monitoring_info.py +2 -1
  61. parsl/executors/high_throughput/mpi_executor.py +113 -0
  62. parsl/executors/high_throughput/mpi_prefix_composer.py +10 -11
  63. parsl/executors/high_throughput/mpi_resource_management.py +6 -17
  64. parsl/executors/high_throughput/probe.py +9 -7
  65. parsl/executors/high_throughput/process_worker_pool.py +115 -77
  66. parsl/executors/high_throughput/zmq_pipes.py +81 -23
  67. parsl/executors/radical/executor.py +130 -79
  68. parsl/executors/radical/rpex_resources.py +17 -15
  69. parsl/executors/radical/rpex_worker.py +4 -3
  70. parsl/executors/status_handling.py +157 -51
  71. parsl/executors/taskvine/__init__.py +1 -1
  72. parsl/executors/taskvine/errors.py +1 -1
  73. parsl/executors/taskvine/exec_parsl_function.py +2 -2
  74. parsl/executors/taskvine/executor.py +41 -57
  75. parsl/executors/taskvine/factory.py +1 -1
  76. parsl/executors/taskvine/factory_config.py +1 -1
  77. parsl/executors/taskvine/manager.py +18 -13
  78. parsl/executors/taskvine/manager_config.py +9 -5
  79. parsl/executors/threads.py +6 -6
  80. parsl/executors/workqueue/errors.py +1 -1
  81. parsl/executors/workqueue/exec_parsl_function.py +6 -5
  82. parsl/executors/workqueue/executor.py +64 -63
  83. parsl/executors/workqueue/parsl_coprocess.py +1 -1
  84. parsl/jobs/error_handlers.py +2 -2
  85. parsl/jobs/job_status_poller.py +30 -113
  86. parsl/jobs/states.py +7 -2
  87. parsl/jobs/strategy.py +43 -31
  88. parsl/launchers/__init__.py +12 -3
  89. parsl/launchers/errors.py +1 -1
  90. parsl/launchers/launchers.py +6 -12
  91. parsl/log_utils.py +9 -6
  92. parsl/monitoring/db_manager.py +59 -95
  93. parsl/monitoring/errors.py +6 -0
  94. parsl/monitoring/monitoring.py +87 -356
  95. parsl/monitoring/queries/pandas.py +1 -2
  96. parsl/monitoring/radios/base.py +13 -0
  97. parsl/monitoring/radios/filesystem.py +52 -0
  98. parsl/monitoring/radios/htex.py +57 -0
  99. parsl/monitoring/radios/multiprocessing.py +17 -0
  100. parsl/monitoring/radios/udp.py +56 -0
  101. parsl/monitoring/radios/zmq.py +17 -0
  102. parsl/monitoring/remote.py +33 -37
  103. parsl/monitoring/router.py +212 -0
  104. parsl/monitoring/types.py +5 -6
  105. parsl/monitoring/visualization/app.py +4 -2
  106. parsl/monitoring/visualization/models.py +0 -1
  107. parsl/monitoring/visualization/plots/default/workflow_plots.py +11 -4
  108. parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
  109. parsl/monitoring/visualization/utils.py +0 -1
  110. parsl/monitoring/visualization/views.py +16 -8
  111. parsl/multiprocessing.py +0 -1
  112. parsl/process_loggers.py +1 -2
  113. parsl/providers/__init__.py +8 -17
  114. parsl/providers/aws/aws.py +2 -3
  115. parsl/providers/azure/azure.py +4 -5
  116. parsl/providers/base.py +2 -18
  117. parsl/providers/cluster_provider.py +4 -12
  118. parsl/providers/condor/condor.py +7 -17
  119. parsl/providers/errors.py +2 -2
  120. parsl/providers/googlecloud/googlecloud.py +2 -1
  121. parsl/providers/grid_engine/grid_engine.py +5 -14
  122. parsl/providers/kubernetes/kube.py +80 -40
  123. parsl/providers/local/local.py +13 -26
  124. parsl/providers/lsf/lsf.py +5 -23
  125. parsl/providers/pbspro/pbspro.py +5 -17
  126. parsl/providers/slurm/slurm.py +81 -39
  127. parsl/providers/torque/torque.py +3 -14
  128. parsl/serialize/__init__.py +8 -3
  129. parsl/serialize/base.py +1 -2
  130. parsl/serialize/concretes.py +5 -4
  131. parsl/serialize/facade.py +3 -3
  132. parsl/serialize/proxystore.py +3 -2
  133. parsl/tests/__init__.py +1 -1
  134. parsl/tests/configs/azure_single_node.py +4 -5
  135. parsl/tests/configs/bridges.py +3 -2
  136. parsl/tests/configs/cc_in2p3.py +1 -3
  137. parsl/tests/configs/comet.py +2 -1
  138. parsl/tests/configs/ec2_single_node.py +1 -2
  139. parsl/tests/configs/ec2_spot.py +1 -2
  140. parsl/tests/configs/flux_local.py +11 -0
  141. parsl/tests/configs/frontera.py +2 -3
  142. parsl/tests/configs/htex_local.py +3 -5
  143. parsl/tests/configs/htex_local_alternate.py +11 -15
  144. parsl/tests/configs/htex_local_intask_staging.py +5 -9
  145. parsl/tests/configs/htex_local_rsync_staging.py +4 -8
  146. parsl/tests/configs/local_radical.py +1 -3
  147. parsl/tests/configs/local_radical_mpi.py +2 -2
  148. parsl/tests/configs/local_threads_checkpoint_periodic.py +8 -10
  149. parsl/tests/configs/local_threads_monitoring.py +0 -1
  150. parsl/tests/configs/midway.py +2 -2
  151. parsl/tests/configs/nscc_singapore.py +3 -3
  152. parsl/tests/configs/osg_htex.py +1 -1
  153. parsl/tests/configs/petrelkube.py +3 -2
  154. parsl/tests/configs/slurm_local.py +24 -0
  155. parsl/tests/configs/summit.py +1 -0
  156. parsl/tests/configs/taskvine_ex.py +4 -7
  157. parsl/tests/configs/user_opts.py +2 -8
  158. parsl/tests/configs/workqueue_ex.py +4 -6
  159. parsl/tests/conftest.py +27 -13
  160. parsl/tests/integration/test_stress/test_python_simple.py +3 -4
  161. parsl/tests/integration/test_stress/test_python_threads.py +3 -5
  162. parsl/tests/manual_tests/htex_local.py +4 -6
  163. parsl/tests/manual_tests/test_basic.py +1 -0
  164. parsl/tests/manual_tests/test_log_filter.py +3 -1
  165. parsl/tests/manual_tests/test_memory_limits.py +6 -8
  166. parsl/tests/manual_tests/test_regression_220.py +2 -1
  167. parsl/tests/manual_tests/test_udp_simple.py +4 -4
  168. parsl/tests/manual_tests/test_worker_count.py +3 -2
  169. parsl/tests/scaling_tests/htex_local.py +2 -4
  170. parsl/tests/scaling_tests/test_scale.py +0 -9
  171. parsl/tests/scaling_tests/vineex_condor.py +1 -2
  172. parsl/tests/scaling_tests/vineex_local.py +1 -2
  173. parsl/tests/site_tests/site_config_selector.py +1 -6
  174. parsl/tests/site_tests/test_provider.py +4 -2
  175. parsl/tests/site_tests/test_site.py +2 -0
  176. parsl/tests/sites/test_affinity.py +7 -7
  177. parsl/tests/sites/test_dynamic_executor.py +3 -4
  178. parsl/tests/sites/test_ec2.py +3 -2
  179. parsl/tests/sites/test_worker_info.py +4 -5
  180. parsl/tests/test_aalst_patterns.py +0 -1
  181. parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
  182. parsl/tests/test_bash_apps/test_basic.py +10 -4
  183. parsl/tests/test_bash_apps/test_error_codes.py +5 -7
  184. parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
  185. parsl/tests/test_bash_apps/test_kwarg_storage.py +1 -1
  186. parsl/tests/test_bash_apps/test_memoize.py +2 -8
  187. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +9 -14
  188. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +9 -14
  189. parsl/tests/test_bash_apps/test_multiline.py +1 -1
  190. parsl/tests/test_bash_apps/test_pipeline.py +1 -1
  191. parsl/tests/test_bash_apps/test_std_uri.py +123 -0
  192. parsl/tests/test_bash_apps/test_stdout.py +33 -8
  193. parsl/tests/test_callables.py +2 -2
  194. parsl/tests/test_checkpointing/test_periodic.py +21 -39
  195. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
  196. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
  197. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
  198. parsl/tests/test_checkpointing/test_regression_239.py +1 -1
  199. parsl/tests/test_checkpointing/test_task_exit.py +2 -3
  200. parsl/tests/test_docs/test_from_slides.py +5 -2
  201. parsl/tests/test_docs/test_kwargs.py +4 -1
  202. parsl/tests/test_docs/test_tutorial_1.py +1 -2
  203. parsl/tests/test_docs/test_workflow1.py +2 -2
  204. parsl/tests/test_docs/test_workflow2.py +0 -1
  205. parsl/tests/test_error_handling/test_rand_fail.py +2 -2
  206. parsl/tests/test_error_handling/test_resource_spec.py +10 -12
  207. parsl/tests/test_error_handling/test_retries.py +6 -16
  208. parsl/tests/test_error_handling/test_retry_handler.py +1 -0
  209. parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
  210. parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
  211. parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
  212. parsl/tests/test_execute_task.py +29 -0
  213. parsl/tests/test_flux.py +1 -1
  214. parsl/tests/test_htex/test_basic.py +2 -3
  215. parsl/tests/test_htex/test_block_manager_selector_unit.py +20 -0
  216. parsl/tests/test_htex/test_command_client_timeout.py +66 -0
  217. parsl/tests/test_htex/test_connected_blocks.py +3 -2
  218. parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
  219. parsl/tests/test_htex/test_disconnected_blocks.py +6 -5
  220. parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
  221. parsl/tests/test_htex/test_drain.py +79 -0
  222. parsl/tests/test_htex/test_htex.py +51 -25
  223. parsl/tests/test_htex/test_manager_failure.py +0 -1
  224. parsl/tests/test_htex/test_manager_selector_by_block.py +51 -0
  225. parsl/tests/test_htex/test_managers_command.py +36 -0
  226. parsl/tests/test_htex/test_missing_worker.py +2 -12
  227. parsl/tests/test_htex/test_multiple_disconnected_blocks.py +9 -9
  228. parsl/tests/test_htex/test_resource_spec_validation.py +45 -0
  229. parsl/tests/test_htex/test_zmq_binding.py +29 -8
  230. parsl/tests/test_monitoring/test_app_names.py +86 -0
  231. parsl/tests/test_monitoring/test_basic.py +73 -25
  232. parsl/tests/test_monitoring/test_db_locks.py +6 -4
  233. parsl/tests/test_monitoring/test_fuzz_zmq.py +19 -8
  234. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +80 -0
  235. parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
  236. parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
  237. parsl/tests/test_monitoring/test_stdouterr.py +134 -0
  238. parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
  239. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +33 -26
  240. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +28 -11
  241. parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
  242. parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
  243. parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
  244. parsl/tests/test_mpi_apps/test_resource_spec.py +42 -49
  245. parsl/tests/test_providers/test_kubernetes_provider.py +102 -0
  246. parsl/tests/test_providers/test_local_provider.py +3 -132
  247. parsl/tests/test_providers/test_pbspro_template.py +2 -3
  248. parsl/tests/test_providers/test_slurm_template.py +2 -3
  249. parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
  250. parsl/tests/test_python_apps/test_context_manager.py +128 -0
  251. parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
  252. parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
  253. parsl/tests/test_python_apps/test_fail.py +0 -25
  254. parsl/tests/test_python_apps/test_futures.py +2 -1
  255. parsl/tests/test_python_apps/test_inputs_default.py +22 -0
  256. parsl/tests/test_python_apps/test_join.py +0 -1
  257. parsl/tests/test_python_apps/test_lifted.py +11 -7
  258. parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
  259. parsl/tests/test_python_apps/test_outputs.py +1 -1
  260. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
  261. parsl/tests/test_radical/test_mpi_funcs.py +1 -2
  262. parsl/tests/test_regression/test_1480.py +2 -1
  263. parsl/tests/test_regression/test_1653.py +2 -1
  264. parsl/tests/test_regression/test_226.py +1 -0
  265. parsl/tests/test_regression/test_2652.py +1 -0
  266. parsl/tests/test_regression/test_69a.py +0 -1
  267. parsl/tests/test_regression/test_854.py +4 -2
  268. parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
  269. parsl/tests/test_regression/test_98.py +0 -1
  270. parsl/tests/test_scaling/test_block_error_handler.py +9 -4
  271. parsl/tests/test_scaling/test_regression_1621.py +11 -15
  272. parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +84 -0
  273. parsl/tests/test_scaling/test_regression_3696_oscillation.py +103 -0
  274. parsl/tests/test_scaling/test_scale_down.py +2 -5
  275. parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +6 -18
  276. parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +71 -0
  277. parsl/tests/test_scaling/test_shutdown_scalein.py +73 -0
  278. parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +90 -0
  279. parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
  280. parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
  281. parsl/tests/test_serialization/test_basic.py +2 -1
  282. parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
  283. parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
  284. parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
  285. parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
  286. parsl/tests/test_shutdown/test_kill_monitoring.py +64 -0
  287. parsl/tests/test_staging/staging_provider.py +2 -2
  288. parsl/tests/test_staging/test_1316.py +3 -4
  289. parsl/tests/test_staging/test_docs_1.py +2 -1
  290. parsl/tests/test_staging/test_docs_2.py +2 -1
  291. parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
  292. parsl/tests/{test_data → test_staging}/test_file.py +6 -6
  293. parsl/tests/{test_data → test_staging}/test_output_chain_filenames.py +3 -0
  294. parsl/tests/test_staging/test_staging_ftp.py +1 -0
  295. parsl/tests/test_staging/test_staging_https.py +5 -2
  296. parsl/tests/test_staging/test_staging_stdout.py +64 -0
  297. parsl/tests/test_staging/test_zip_in.py +39 -0
  298. parsl/tests/test_staging/test_zip_out.py +110 -0
  299. parsl/tests/test_staging/test_zip_to_zip.py +41 -0
  300. parsl/tests/test_summary.py +2 -2
  301. parsl/tests/test_thread_parallelism.py +0 -1
  302. parsl/tests/test_threads/test_configs.py +1 -2
  303. parsl/tests/test_threads/test_lazy_errors.py +2 -2
  304. parsl/tests/test_utils/test_execute_wait.py +35 -0
  305. parsl/tests/test_utils/test_sanitize_dns.py +76 -0
  306. parsl/tests/unit/test_address.py +20 -0
  307. parsl/tests/unit/test_file.py +99 -0
  308. parsl/tests/unit/test_usage_tracking.py +66 -0
  309. parsl/usage_tracking/api.py +65 -0
  310. parsl/usage_tracking/levels.py +6 -0
  311. parsl/usage_tracking/usage.py +104 -62
  312. parsl/utils.py +139 -6
  313. parsl/version.py +1 -1
  314. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/exec_parsl_function.py +6 -5
  315. parsl-2025.1.13.data/scripts/interchange.py +649 -0
  316. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/process_worker_pool.py +115 -77
  317. parsl-2025.1.13.dist-info/METADATA +96 -0
  318. parsl-2025.1.13.dist-info/RECORD +462 -0
  319. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/WHEEL +1 -1
  320. parsl/channels/__init__.py +0 -7
  321. parsl/channels/base.py +0 -141
  322. parsl/channels/errors.py +0 -113
  323. parsl/channels/local/local.py +0 -164
  324. parsl/channels/oauth_ssh/oauth_ssh.py +0 -110
  325. parsl/channels/ssh/ssh.py +0 -276
  326. parsl/channels/ssh_il/__init__.py +0 -0
  327. parsl/channels/ssh_il/ssh_il.py +0 -74
  328. parsl/configs/ad_hoc.py +0 -35
  329. parsl/executors/radical/rpex_master.py +0 -42
  330. parsl/monitoring/radios.py +0 -175
  331. parsl/providers/ad_hoc/__init__.py +0 -0
  332. parsl/providers/ad_hoc/ad_hoc.py +0 -248
  333. parsl/providers/cobalt/__init__.py +0 -0
  334. parsl/providers/cobalt/cobalt.py +0 -236
  335. parsl/providers/cobalt/template.py +0 -17
  336. parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
  337. parsl/tests/configs/cooley_htex.py +0 -37
  338. parsl/tests/configs/htex_ad_hoc_cluster.py +0 -28
  339. parsl/tests/configs/local_adhoc.py +0 -18
  340. parsl/tests/configs/swan_htex.py +0 -43
  341. parsl/tests/configs/theta.py +0 -37
  342. parsl/tests/integration/test_channels/__init__.py +0 -0
  343. parsl/tests/integration/test_channels/test_channels.py +0 -17
  344. parsl/tests/integration/test_channels/test_local_channel.py +0 -42
  345. parsl/tests/integration/test_channels/test_scp_1.py +0 -45
  346. parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
  347. parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
  348. parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
  349. parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
  350. parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -48
  351. parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -88
  352. parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
  353. parsl/tests/sites/test_local_adhoc.py +0 -61
  354. parsl/tests/test_channels/__init__.py +0 -0
  355. parsl/tests/test_channels/test_large_output.py +0 -22
  356. parsl/tests/test_data/__init__.py +0 -0
  357. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -51
  358. parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -16
  359. parsl-2024.3.11.dist-info/METADATA +0 -98
  360. parsl-2024.3.11.dist-info/RECORD +0 -447
  361. parsl/{channels/local → monitoring/radios}/__init__.py +0 -0
  362. parsl/{channels/oauth_ssh → tests/test_shutdown}/__init__.py +0 -0
  363. parsl/tests/{test_data → test_staging}/test_file_apps.py +0 -0
  364. parsl/tests/{test_data → test_staging}/test_file_staging.py +0 -0
  365. parsl/{channels/ssh → tests/unit}/__init__.py +0 -0
  366. {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/parsl_coprocess.py +1 -1
  367. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/LICENSE +0 -0
  368. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/entry_points.txt +0 -0
  369. {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/top_level.txt +0 -0
@@ -4,15 +4,6 @@ import argparse
4
4
  import time
5
5
 
6
6
  import parsl
7
-
8
- # from parsl.tests.configs.htex_local import config
9
- # from htex_local import config
10
- # from parsl.configs.local_threads import config
11
- # from parsl.configs.local_ipp import config
12
-
13
- # parsl.set_stream_logger()
14
- # config.executors[0].provider.tasks_per_node = 4
15
- # parsl.load(config)
16
7
  from parsl.app.app import python_app # , bash_app
17
8
 
18
9
 
@@ -1,6 +1,5 @@
1
1
  from parsl.config import Config
2
- from parsl.executors.taskvine import TaskVineExecutor
3
- from parsl.executors.taskvine import TaskVineManagerConfig
2
+ from parsl.executors.taskvine import TaskVineExecutor, TaskVineManagerConfig
4
3
  from parsl.providers import CondorProvider
5
4
 
6
5
  config = Config(
@@ -1,6 +1,5 @@
1
1
  from parsl.config import Config
2
- from parsl.executors.taskvine import TaskVineExecutor
3
- from parsl.executors.taskvine import TaskVineManagerConfig
2
+ from parsl.executors.taskvine import TaskVineExecutor, TaskVineManagerConfig
4
3
  from parsl.providers import LocalProvider
5
4
 
6
5
  config = Config(
@@ -7,12 +7,7 @@ def fresh_config():
7
7
  hostname = os.getenv('PARSL_HOSTNAME', platform.uname().node)
8
8
  print("Loading config for {}".format(hostname))
9
9
 
10
- if 'thetalogin' in hostname:
11
- from parsl.tests.configs.theta import fresh_config
12
- config = fresh_config()
13
- print("Loading Theta config")
14
-
15
- elif 'frontera' in hostname:
10
+ if 'frontera' in hostname:
16
11
  print("Loading Frontera config")
17
12
  from parsl.tests.configs.frontera import fresh_config
18
13
  config = fresh_config()
@@ -1,8 +1,10 @@
1
1
  import argparse
2
2
  import logging
3
+ import time
4
+
3
5
  import pytest
6
+
4
7
  import parsl
5
- import time
6
8
  from parsl.app.app import python_app # , bash_app
7
9
  from parsl.jobs.states import JobState
8
10
  from parsl.tests.site_tests.site_config_selector import fresh_config
@@ -58,7 +60,7 @@ def test_provider():
58
60
  logger.info("Job in terminal state")
59
61
 
60
62
  _, current_jobs = executor._get_block_and_job_ids()
61
- # PR 1952 stoped removing scale_in blocks from self.blocks
63
+ # PR 1952 stoped removing scale_in blocks from self.blocks_to_job_id
62
64
  # A new PR will handle removing blocks from self.block
63
65
  # this includes failed/completed/canceled blocks
64
66
  assert len(current_jobs) == 1, "Expected current_jobs == 1"
@@ -1,5 +1,7 @@
1
1
  import argparse
2
+
2
3
  import pytest
4
+
3
5
  import parsl
4
6
  from parsl.app.app import python_app # , bash_app
5
7
  from parsl.tests.site_tests.site_config_selector import fresh_config
@@ -1,12 +1,13 @@
1
1
  """Tests related to assigning workers to specific compute units"""
2
2
 
3
- from parsl.providers import LocalProvider
4
- from parsl.channels import LocalChannel
3
+ import os
4
+
5
+ import pytest
6
+
7
+ from parsl import python_app
5
8
  from parsl.config import Config
6
9
  from parsl.executors import HighThroughputExecutor
7
- from parsl import python_app
8
- import pytest
9
- import os
10
+ from parsl.providers import LocalProvider
10
11
 
11
12
 
12
13
  def local_config():
@@ -20,7 +21,6 @@ def local_config():
20
21
  available_accelerators=2,
21
22
  encrypted=True,
22
23
  provider=LocalProvider(
23
- channel=LocalChannel(),
24
24
  init_blocks=1,
25
25
  max_blocks=1,
26
26
  ),
@@ -32,8 +32,8 @@ def local_config():
32
32
 
33
33
  @python_app
34
34
  def get_worker_info():
35
- from time import sleep
36
35
  import os
36
+ from time import sleep
37
37
  rank = int(os.environ['PARSL_WORKER_RANK'])
38
38
  aff = os.sched_getaffinity(0)
39
39
  device = os.environ.get('CUDA_VISIBLE_DEVICES')
@@ -1,10 +1,10 @@
1
+ import pytest
2
+
1
3
  import parsl
4
+ from parsl.app.app import python_app
2
5
  from parsl.executors import HighThroughputExecutor
3
6
  from parsl.executors.threads import ThreadPoolExecutor
4
7
  from parsl.providers import LocalProvider
5
- from parsl.app.app import python_app
6
-
7
- import pytest
8
8
 
9
9
 
10
10
  @python_app(executors=['threads'])
@@ -75,4 +75,3 @@ def test_dynamic_executor():
75
75
  print("Done testing")
76
76
 
77
77
  dfk.cleanup()
78
- parsl.clear()
@@ -1,10 +1,11 @@
1
- import parsl
1
+ import logging
2
+
2
3
  import pytest
3
4
 
5
+ import parsl
4
6
  from parsl.app.app import python_app
5
7
  from parsl.tests.configs.ec2_single_node import config
6
8
 
7
- import logging
8
9
  logger = logging.getLogger(__name__)
9
10
 
10
11
  local_config = config
@@ -1,11 +1,11 @@
1
1
  """Tests related to Parsl workers being able to access their worker ID"""
2
2
 
3
- from parsl.providers import LocalProvider
4
- from parsl.channels import LocalChannel
3
+ import pytest
4
+
5
+ from parsl import python_app
5
6
  from parsl.config import Config
6
7
  from parsl.executors import HighThroughputExecutor
7
- from parsl import python_app
8
- import pytest
8
+ from parsl.providers import LocalProvider
9
9
 
10
10
 
11
11
  def local_config():
@@ -17,7 +17,6 @@ def local_config():
17
17
  max_workers_per_node=4,
18
18
  encrypted=True,
19
19
  provider=LocalProvider(
20
- channel=LocalChannel(),
21
20
  init_blocks=1,
22
21
  max_blocks=1,
23
22
  ),
@@ -6,7 +6,6 @@ import pytest
6
6
  from parsl.app.app import python_app
7
7
  from parsl.tests.configs.local_threads import config
8
8
 
9
-
10
9
  pytestmark = pytest.mark.skip('not asserting anything')
11
10
 
12
11
 
@@ -1,9 +1,9 @@
1
- import parsl
2
1
  import pytest
3
2
 
3
+ import parsl
4
4
  from parsl.app.app import bash_app
5
- from parsl.tests.configs.local_threads import config
6
5
  from parsl.app.errors import AppTimeout
6
+ from parsl.tests.configs.local_threads import config
7
7
 
8
8
 
9
9
  @bash_app
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import os
2
3
  import random
3
4
  import re
@@ -23,7 +24,7 @@ def foo(x, y, z=10, stdout=None, label=None):
23
24
  return f"echo {x} {y} {z}"
24
25
 
25
26
 
26
- @pytest.mark.issue363
27
+ @pytest.mark.shared_fs
27
28
  def test_command_format_1(tmpd_cwd):
28
29
  """Testing command format for BashApps"""
29
30
 
@@ -38,8 +39,8 @@ def test_command_format_1(tmpd_cwd):
38
39
  assert so_content == "1 4 10"
39
40
 
40
41
 
41
- @pytest.mark.issue363
42
- def test_auto_log_filename_format():
42
+ @pytest.mark.shared_fs
43
+ def test_auto_log_filename_format(caplog):
43
44
  """Testing auto log filename format for BashApps
44
45
  """
45
46
  app_label = "label_test_auto_log_filename_format"
@@ -51,6 +52,8 @@ def test_auto_log_filename_format():
51
52
  foo_future.result())
52
53
 
53
54
  log_fpath = foo_future.stdout
55
+ assert isinstance(log_fpath, str)
56
+
54
57
  log_pattern = fr".*/task_\d+_foo_{app_label}"
55
58
  assert re.match(log_pattern, log_fpath), 'Output file "{0}" does not match pattern "{1}"'.format(
56
59
  log_fpath, log_pattern)
@@ -61,8 +64,11 @@ def test_auto_log_filename_format():
61
64
  assert contents == '1 {0} 10\n'.format(rand_int), \
62
65
  'Output does not match expected string "1 {0} 10", Got: "{1}"'.format(rand_int, contents)
63
66
 
67
+ for record in caplog.records:
68
+ assert record.levelno < logging.ERROR
69
+
64
70
 
65
- @pytest.mark.issue363
71
+ @pytest.mark.shared_fs
66
72
  def test_parallel_for(tmpd_cwd, n=3):
67
73
  """Testing a simple parallel for loop"""
68
74
  outdir = tmpd_cwd / "outputs/test_parallel"
@@ -4,12 +4,9 @@ import os
4
4
  import pytest
5
5
 
6
6
  import parsl
7
- from parsl.app.app import bash_app
8
7
  import parsl.app.errors as pe
9
-
10
-
8
+ from parsl.app.app import bash_app
11
9
  from parsl.app.errors import BashExitFailure
12
-
13
10
  from parsl.tests.configs.local_threads import fresh_config as local_config
14
11
 
15
12
 
@@ -61,6 +58,7 @@ test_matrix = {
61
58
  whitelist = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', '*threads*')
62
59
 
63
60
 
61
+ @pytest.mark.shared_fs
64
62
  def test_div_0(test_fn=div_0):
65
63
  err_code = test_matrix[test_fn]['exit_code']
66
64
  f = test_fn()
@@ -76,7 +74,7 @@ def test_div_0(test_fn=div_0):
76
74
  os.remove('std.out')
77
75
 
78
76
 
79
- @pytest.mark.issue363
77
+ @pytest.mark.shared_fs
80
78
  def test_bash_misuse(test_fn=bash_misuse):
81
79
  err_code = test_matrix[test_fn]['exit_code']
82
80
  f = test_fn()
@@ -91,7 +89,7 @@ def test_bash_misuse(test_fn=bash_misuse):
91
89
  os.remove('std.out')
92
90
 
93
91
 
94
- @pytest.mark.issue363
92
+ @pytest.mark.shared_fs
95
93
  def test_command_not_found(test_fn=command_not_found):
96
94
  err_code = test_matrix[test_fn]['exit_code']
97
95
  f = test_fn()
@@ -108,7 +106,7 @@ def test_command_not_found(test_fn=command_not_found):
108
106
  return True
109
107
 
110
108
 
111
- @pytest.mark.issue363
109
+ @pytest.mark.shared_fs
112
110
  def test_not_executable(test_fn=not_executable):
113
111
  err_code = test_matrix[test_fn]['exit_code']
114
112
  f = test_fn()
@@ -0,0 +1,25 @@
1
+ import pytest
2
+
3
+ from parsl import AUTO_LOGNAME, Config, bash_app, python_app
4
+ from parsl.executors import ThreadPoolExecutor
5
+
6
+
7
+ def local_config():
8
+ return Config(executors=[ThreadPoolExecutor()])
9
+
10
+
11
+ @pytest.mark.local
12
+ def test_default_inputs():
13
+ @python_app
14
+ def identity(inp):
15
+ return inp
16
+
17
+ @bash_app
18
+ def sum_inputs(inputs=[identity(1), identity(2)], stdout=AUTO_LOGNAME):
19
+ calc = sum(inputs)
20
+ return f"echo {calc}"
21
+
22
+ fut = sum_inputs()
23
+ fut.result()
24
+ with open(fut.stdout, 'r') as f:
25
+ assert int(f.read()) == 3
@@ -8,7 +8,7 @@ def foo(z=2, stdout=None):
8
8
  return f"echo {z}"
9
9
 
10
10
 
11
- @pytest.mark.issue363
11
+ @pytest.mark.shared_fs
12
12
  def test_command_format_1(tmpd_cwd):
13
13
  """Testing command format for BashApps
14
14
  """
@@ -9,10 +9,7 @@ def fail_on_presence(outputs=()):
9
9
  return 'if [ -f {0} ] ; then exit 1 ; else touch {0}; fi'.format(outputs[0])
10
10
 
11
11
 
12
- # This test is an oddity that requires a shared-FS and simply
13
- # won't work if there's a staging provider.
14
- # @pytest.mark.sharedFS_required
15
- @pytest.mark.issue363
12
+ @pytest.mark.shared_fs
16
13
  def test_bash_memoization(tmpd_cwd, n=2):
17
14
  """Testing bash memoization
18
15
  """
@@ -30,10 +27,7 @@ def fail_on_presence_kw(outputs=(), foo=None):
30
27
  return 'if [ -f {0} ] ; then exit 1 ; else touch {0}; fi'.format(outputs[0])
31
28
 
32
29
 
33
- # This test is an oddity that requires a shared-FS and simply
34
- # won't work if there's a staging provider.
35
- # @pytest.mark.sharedFS_required
36
- @pytest.mark.issue363
30
+ @pytest.mark.shared_fs
37
31
  def test_bash_memoization_keywords(tmpd_cwd, n=2):
38
32
  """Testing bash memoization
39
33
  """
@@ -1,4 +1,5 @@
1
1
  import os
2
+
2
3
  import pytest
3
4
 
4
5
  import parsl
@@ -22,25 +23,19 @@ def no_checkpoint_stdout_app_ignore_args(stdout=None):
22
23
  return "echo X"
23
24
 
24
25
 
25
- @pytest.mark.issue363
26
- def test_memo_stdout():
26
+ @pytest.mark.shared_fs
27
+ def test_memo_stdout(tmpd_cwd):
28
+ path_x = tmpd_cwd / "test.memo.stdout.x"
27
29
 
28
30
  # this should run and create a file named after path_x
29
- path_x = "test.memo.stdout.x"
30
- if os.path.exists(path_x):
31
- os.remove(path_x)
32
-
33
- no_checkpoint_stdout_app_ignore_args(stdout=path_x).result()
34
- assert os.path.exists(path_x)
35
-
36
- # this should be memoized, so not create benc.test.y
37
- path_y = "test.memo.stdout.y"
31
+ no_checkpoint_stdout_app_ignore_args(stdout=str(path_x)).result()
32
+ assert path_x.exists()
38
33
 
39
- if os.path.exists(path_y):
40
- os.remove(path_y)
34
+ # this should be memoized, so should not get created
35
+ path_y = tmpd_cwd / "test.memo.stdout.y"
41
36
 
42
37
  no_checkpoint_stdout_app_ignore_args(stdout=path_y).result()
43
- assert not os.path.exists(path_y)
38
+ assert not path_y.exists(), "For memoization, expected NO file written"
44
39
 
45
40
  # this should also be memoized, so not create an arbitrary name
46
41
  z_fut = no_checkpoint_stdout_app_ignore_args(stdout=parsl.AUTO_LOGNAME)
@@ -1,9 +1,8 @@
1
1
  import copy
2
- import os
3
- import pytest
4
-
5
2
  from typing import List
6
3
 
4
+ import pytest
5
+
7
6
  import parsl
8
7
  from parsl.app.app import bash_app
9
8
 
@@ -30,22 +29,18 @@ def no_checkpoint_stdout_app(stdout=None):
30
29
  return "echo X"
31
30
 
32
31
 
33
- @pytest.mark.issue363
34
- def test_memo_stdout():
35
-
32
+ @pytest.mark.shared_fs
33
+ def test_memo_stdout(tmpd_cwd):
36
34
  assert const_list_x == const_list_x_arg
37
35
 
38
- path_x = "test.memo.stdout.x"
39
- if os.path.exists(path_x):
40
- os.remove(path_x)
36
+ path_x = tmpd_cwd / "test.memo.stdout.x"
41
37
 
42
38
  # this should run and create a file named after path_x
43
- no_checkpoint_stdout_app(stdout=path_x).result()
44
- assert os.path.exists(path_x)
39
+ no_checkpoint_stdout_app(stdout=str(path_x)).result()
40
+ path_x.unlink(missing_ok=False)
45
41
 
46
- os.remove(path_x)
47
- no_checkpoint_stdout_app(stdout=path_x).result()
48
- assert not os.path.exists(path_x)
42
+ no_checkpoint_stdout_app(stdout=str(path_x)).result()
43
+ assert not path_x.exists(), "For memoization, expected NO file written"
49
44
 
50
45
  # this should also be memoized, so not create an arbitrary name
51
46
  z_fut = no_checkpoint_stdout_app(stdout=parsl.AUTO_LOGNAME)
@@ -14,7 +14,7 @@ def multiline(inputs=(), outputs=(), stderr=None, stdout=None):
14
14
  """.format(inputs=inputs, outputs=outputs)
15
15
 
16
16
 
17
- @pytest.mark.issue363
17
+ @pytest.mark.shared_fs
18
18
  def test_multiline(tmpd_cwd):
19
19
  so, se = tmpd_cwd / "std.out", tmpd_cwd / "std.err"
20
20
  f = multiline(
@@ -1,8 +1,8 @@
1
1
  import pytest
2
2
 
3
3
  from parsl.app.app import bash_app
4
- from parsl.data_provider.files import File
5
4
  from parsl.app.futures import DataFuture
5
+ from parsl.data_provider.files import File
6
6
 
7
7
 
8
8
  @bash_app
@@ -0,0 +1,123 @@
1
+ import logging
2
+ import zipfile
3
+ from functools import partial
4
+
5
+ import pytest
6
+
7
+ import parsl
8
+ from parsl.app.futures import DataFuture
9
+ from parsl.data_provider.files import File
10
+ from parsl.executors import ThreadPoolExecutor
11
+
12
+
13
+ @parsl.bash_app
14
+ def app_stdout(stdout=parsl.AUTO_LOGNAME):
15
+ return "echo hello"
16
+
17
+
18
+ def const_str(cpath, task_record, err_or_out):
19
+ return cpath
20
+
21
+
22
+ def const_with_cpath(autopath_specifier, content_path, caplog):
23
+ with parsl.load(parsl.Config(std_autopath=partial(const_str, autopath_specifier))):
24
+ fut = app_stdout()
25
+
26
+ # we don't have to wait for a result to check this attributes
27
+ assert fut.stdout is autopath_specifier
28
+
29
+ # there is no DataFuture to wait for in the str case: the model is that
30
+ # the stdout will be immediately available on task completion.
31
+ fut.result()
32
+
33
+ with open(content_path, "r") as file:
34
+ assert file.readlines() == ["hello\n"]
35
+
36
+ for record in caplog.records:
37
+ assert record.levelno < logging.ERROR
38
+
39
+
40
+ @pytest.mark.local
41
+ def test_std_autopath_const_str(caplog, tmpd_cwd):
42
+ """Tests str and tuple mode autopaths with constant autopath, which should
43
+ all be passed through unmodified.
44
+ """
45
+ cpath = str(tmpd_cwd / "CONST")
46
+ const_with_cpath(cpath, cpath, caplog)
47
+
48
+
49
+ @pytest.mark.local
50
+ def test_std_autopath_const_pathlike(caplog, tmpd_cwd):
51
+ cpath = tmpd_cwd / "CONST"
52
+ const_with_cpath(cpath, cpath, caplog)
53
+
54
+
55
+ @pytest.mark.local
56
+ def test_std_autopath_const_tuples(caplog, tmpd_cwd):
57
+ file = tmpd_cwd / "CONST"
58
+ cpath = (file, "w")
59
+ const_with_cpath(cpath, file, caplog)
60
+
61
+
62
+ class URIFailError(Exception):
63
+ pass
64
+
65
+
66
+ def fail_uri(task_record, err_or_out):
67
+ raise URIFailError("Deliberate failure in std stream filename generation")
68
+
69
+
70
+ @pytest.mark.local
71
+ def test_std_autopath_fail(caplog):
72
+ with parsl.load(parsl.Config(std_autopath=fail_uri)):
73
+ with pytest.raises(URIFailError):
74
+ app_stdout()
75
+
76
+
77
+ @parsl.bash_app
78
+ def app_both(stdout=parsl.AUTO_LOGNAME, stderr=parsl.AUTO_LOGNAME):
79
+ return "echo hello; echo goodbye >&2"
80
+
81
+
82
+ def zip_uri(base, task_record, err_or_out):
83
+ """Should generate Files in base.zip like app_both.0.out or app_both.123.err"""
84
+ zip_path = base / "base.zip"
85
+ file = f"{task_record['func_name']}.{task_record['id']}.{task_record['try_id']}.{err_or_out}"
86
+ return File(f"zip:{zip_path}/{file}")
87
+
88
+
89
+ @pytest.mark.local
90
+ def test_std_autopath_zip(caplog, tmpd_cwd):
91
+ with parsl.load(parsl.Config(run_dir=str(tmpd_cwd),
92
+ executors=[ThreadPoolExecutor(working_dir=str(tmpd_cwd))],
93
+ std_autopath=partial(zip_uri, tmpd_cwd))):
94
+ futs = []
95
+
96
+ for _ in range(10):
97
+ fut = app_both()
98
+
99
+ # assertions that should hold after submission
100
+ assert isinstance(fut.stdout, DataFuture)
101
+ assert fut.stdout.file_obj.url.startswith("zip")
102
+
103
+ futs.append(fut)
104
+
105
+ # Barrier for all the stageouts to complete so that we can
106
+ # poke at the zip file.
107
+ [(fut.stdout.result(), fut.stderr.result()) for fut in futs]
108
+
109
+ with zipfile.ZipFile(tmpd_cwd / "base.zip") as z:
110
+ for fut in futs:
111
+
112
+ assert fut.done(), "AppFuture should be done if stageout is done"
113
+
114
+ stdout_relative_path = f"app_both.{fut.tid}.0.stdout"
115
+ with z.open(stdout_relative_path) as f:
116
+ assert f.readlines() == [b'hello\n']
117
+
118
+ stderr_relative_path = f"app_both.{fut.tid}.0.stderr"
119
+ with z.open(stderr_relative_path) as f:
120
+ assert f.readlines()[-1] == b'goodbye\n'
121
+
122
+ for record in caplog.records:
123
+ assert record.levelno < logging.ERROR
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import os
2
3
 
3
4
  import pytest
@@ -15,7 +16,6 @@ def echo_to_streams(msg, stderr=None, stdout=None):
15
16
  whitelist = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', '*threads*')
16
17
 
17
18
  speclist = (
18
- '/bad/dir/t.out',
19
19
  ['t3.out', 'w'],
20
20
  ('t4.out', None),
21
21
  (42, 'w'),
@@ -25,7 +25,6 @@ speclist = (
25
25
  )
26
26
 
27
27
  testids = [
28
- 'nonexistent_dir',
29
28
  'list_not_tuple',
30
29
  'null_mode',
31
30
  'not_a_string',
@@ -35,7 +34,6 @@ testids = [
35
34
  ]
36
35
 
37
36
 
38
- @pytest.mark.issue363
39
37
  @pytest.mark.parametrize('spec', speclist, ids=testids)
40
38
  def test_bad_stdout_specs(spec):
41
39
  """Testing bad stdout spec cases"""
@@ -54,7 +52,27 @@ def test_bad_stdout_specs(spec):
54
52
  assert False, "Did not raise expected exception"
55
53
 
56
54
 
57
- @pytest.mark.issue363
55
+ @pytest.mark.issue3328
56
+ @pytest.mark.unix_filesystem_permissions_required
57
+ def test_bad_stdout_file():
58
+ """Testing bad stderr file"""
59
+
60
+ o = "/bad/dir/t2.out"
61
+
62
+ fn = echo_to_streams("Hello world", stdout=o, stderr='t.err')
63
+
64
+ try:
65
+ fn.result()
66
+ except perror.BadStdStreamFile:
67
+ pass
68
+ else:
69
+ assert False, "Did not raise expected exception BadStdStreamFile"
70
+
71
+ return
72
+
73
+
74
+ @pytest.mark.issue3328
75
+ @pytest.mark.unix_filesystem_permissions_required
58
76
  def test_bad_stderr_file():
59
77
  """Testing bad stderr file"""
60
78
 
@@ -72,8 +90,9 @@ def test_bad_stderr_file():
72
90
  return
73
91
 
74
92
 
75
- @pytest.mark.issue363
76
- def test_stdout_truncate(tmpd_cwd):
93
+ @pytest.mark.executor_supports_std_stream_tuples
94
+ @pytest.mark.shared_fs
95
+ def test_stdout_truncate(tmpd_cwd, caplog):
77
96
  """Testing truncation of prior content of stdout"""
78
97
 
79
98
  out = (str(tmpd_cwd / 't1.out'), 'w')
@@ -88,9 +107,12 @@ def test_stdout_truncate(tmpd_cwd):
88
107
  assert len1 == 1
89
108
  assert len1 == len2
90
109
 
110
+ for record in caplog.records:
111
+ assert record.levelno < logging.ERROR
91
112
 
92
- @pytest.mark.issue363
93
- def test_stdout_append(tmpd_cwd):
113
+
114
+ @pytest.mark.shared_fs
115
+ def test_stdout_append(tmpd_cwd, caplog):
94
116
  """Testing appending to prior content of stdout (default open() mode)"""
95
117
 
96
118
  out = str(tmpd_cwd / 't1.out')
@@ -103,3 +125,6 @@ def test_stdout_append(tmpd_cwd):
103
125
  len2 = len(open(out).readlines())
104
126
 
105
127
  assert len1 == 1 and len2 == 2
128
+
129
+ for record in caplog.records:
130
+ assert record.levelno < logging.ERROR
@@ -5,10 +5,10 @@
5
5
 
6
6
  import importlib
7
7
  import pathlib
8
- import parsl
9
-
10
8
  from functools import partial
11
9
 
10
+ import parsl
11
+
12
12
 
13
13
  @parsl.python_app
14
14
  def app(x):