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.
- parsl/__init__.py +9 -10
- parsl/addresses.py +29 -7
- parsl/app/app.py +7 -8
- parsl/app/bash.py +15 -8
- parsl/app/errors.py +10 -13
- parsl/app/futures.py +8 -10
- parsl/app/python.py +2 -1
- parsl/benchmark/perf.py +2 -1
- parsl/concurrent/__init__.py +2 -2
- parsl/config.py +57 -10
- parsl/configs/ASPIRE1.py +6 -5
- parsl/configs/Azure.py +9 -8
- parsl/configs/bridges.py +6 -4
- parsl/configs/cc_in2p3.py +3 -3
- parsl/configs/ec2.py +3 -1
- parsl/configs/expanse.py +4 -3
- parsl/configs/frontera.py +3 -4
- parsl/configs/htex_local.py +3 -4
- parsl/configs/illinoiscluster.py +3 -1
- parsl/configs/improv.py +34 -0
- parsl/configs/kubernetes.py +4 -3
- parsl/configs/local_threads.py +5 -1
- parsl/configs/midway.py +5 -3
- parsl/configs/osg.py +4 -2
- parsl/configs/polaris.py +4 -2
- parsl/configs/stampede2.py +6 -5
- parsl/configs/summit.py +3 -3
- parsl/configs/toss3_llnl.py +4 -3
- parsl/configs/vineex_local.py +6 -4
- parsl/configs/wqex_local.py +5 -3
- parsl/curvezmq.py +4 -0
- parsl/data_provider/data_manager.py +4 -3
- parsl/data_provider/file_noop.py +1 -2
- parsl/data_provider/files.py +3 -3
- parsl/data_provider/ftp.py +1 -3
- parsl/data_provider/globus.py +7 -6
- parsl/data_provider/http.py +2 -2
- parsl/data_provider/rsync.py +1 -1
- parsl/data_provider/staging.py +2 -2
- parsl/data_provider/zip.py +135 -0
- parsl/dataflow/dependency_resolvers.py +115 -0
- parsl/dataflow/dflow.py +262 -224
- parsl/dataflow/errors.py +3 -5
- parsl/dataflow/futures.py +27 -14
- parsl/dataflow/memoization.py +5 -5
- parsl/dataflow/rundirs.py +5 -6
- parsl/dataflow/taskrecord.py +4 -5
- parsl/executors/__init__.py +4 -2
- parsl/executors/base.py +45 -15
- parsl/executors/errors.py +13 -0
- parsl/executors/execute_task.py +37 -0
- parsl/executors/flux/execute_parsl_task.py +3 -3
- parsl/executors/flux/executor.py +18 -19
- parsl/executors/flux/flux_instance_manager.py +26 -27
- parsl/executors/high_throughput/errors.py +43 -3
- parsl/executors/high_throughput/executor.py +316 -282
- parsl/executors/high_throughput/interchange.py +158 -167
- parsl/executors/high_throughput/manager_record.py +5 -0
- parsl/executors/high_throughput/manager_selector.py +55 -0
- parsl/executors/high_throughput/monitoring_info.py +2 -1
- parsl/executors/high_throughput/mpi_executor.py +113 -0
- parsl/executors/high_throughput/mpi_prefix_composer.py +10 -11
- parsl/executors/high_throughput/mpi_resource_management.py +6 -17
- parsl/executors/high_throughput/probe.py +9 -7
- parsl/executors/high_throughput/process_worker_pool.py +115 -77
- parsl/executors/high_throughput/zmq_pipes.py +81 -23
- parsl/executors/radical/executor.py +130 -79
- parsl/executors/radical/rpex_resources.py +17 -15
- parsl/executors/radical/rpex_worker.py +4 -3
- parsl/executors/status_handling.py +157 -51
- parsl/executors/taskvine/__init__.py +1 -1
- parsl/executors/taskvine/errors.py +1 -1
- parsl/executors/taskvine/exec_parsl_function.py +2 -2
- parsl/executors/taskvine/executor.py +41 -57
- parsl/executors/taskvine/factory.py +1 -1
- parsl/executors/taskvine/factory_config.py +1 -1
- parsl/executors/taskvine/manager.py +18 -13
- parsl/executors/taskvine/manager_config.py +9 -5
- parsl/executors/threads.py +6 -6
- parsl/executors/workqueue/errors.py +1 -1
- parsl/executors/workqueue/exec_parsl_function.py +6 -5
- parsl/executors/workqueue/executor.py +64 -63
- parsl/executors/workqueue/parsl_coprocess.py +1 -1
- parsl/jobs/error_handlers.py +2 -2
- parsl/jobs/job_status_poller.py +30 -113
- parsl/jobs/states.py +7 -2
- parsl/jobs/strategy.py +43 -31
- parsl/launchers/__init__.py +12 -3
- parsl/launchers/errors.py +1 -1
- parsl/launchers/launchers.py +6 -12
- parsl/log_utils.py +9 -6
- parsl/monitoring/db_manager.py +59 -95
- parsl/monitoring/errors.py +6 -0
- parsl/monitoring/monitoring.py +87 -356
- parsl/monitoring/queries/pandas.py +1 -2
- parsl/monitoring/radios/base.py +13 -0
- parsl/monitoring/radios/filesystem.py +52 -0
- parsl/monitoring/radios/htex.py +57 -0
- parsl/monitoring/radios/multiprocessing.py +17 -0
- parsl/monitoring/radios/udp.py +56 -0
- parsl/monitoring/radios/zmq.py +17 -0
- parsl/monitoring/remote.py +33 -37
- parsl/monitoring/router.py +212 -0
- parsl/monitoring/types.py +5 -6
- parsl/monitoring/visualization/app.py +4 -2
- parsl/monitoring/visualization/models.py +0 -1
- parsl/monitoring/visualization/plots/default/workflow_plots.py +11 -4
- parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
- parsl/monitoring/visualization/utils.py +0 -1
- parsl/monitoring/visualization/views.py +16 -8
- parsl/multiprocessing.py +0 -1
- parsl/process_loggers.py +1 -2
- parsl/providers/__init__.py +8 -17
- parsl/providers/aws/aws.py +2 -3
- parsl/providers/azure/azure.py +4 -5
- parsl/providers/base.py +2 -18
- parsl/providers/cluster_provider.py +4 -12
- parsl/providers/condor/condor.py +7 -17
- parsl/providers/errors.py +2 -2
- parsl/providers/googlecloud/googlecloud.py +2 -1
- parsl/providers/grid_engine/grid_engine.py +5 -14
- parsl/providers/kubernetes/kube.py +80 -40
- parsl/providers/local/local.py +13 -26
- parsl/providers/lsf/lsf.py +5 -23
- parsl/providers/pbspro/pbspro.py +5 -17
- parsl/providers/slurm/slurm.py +81 -39
- parsl/providers/torque/torque.py +3 -14
- parsl/serialize/__init__.py +8 -3
- parsl/serialize/base.py +1 -2
- parsl/serialize/concretes.py +5 -4
- parsl/serialize/facade.py +3 -3
- parsl/serialize/proxystore.py +3 -2
- parsl/tests/__init__.py +1 -1
- parsl/tests/configs/azure_single_node.py +4 -5
- parsl/tests/configs/bridges.py +3 -2
- parsl/tests/configs/cc_in2p3.py +1 -3
- parsl/tests/configs/comet.py +2 -1
- parsl/tests/configs/ec2_single_node.py +1 -2
- parsl/tests/configs/ec2_spot.py +1 -2
- parsl/tests/configs/flux_local.py +11 -0
- parsl/tests/configs/frontera.py +2 -3
- parsl/tests/configs/htex_local.py +3 -5
- parsl/tests/configs/htex_local_alternate.py +11 -15
- parsl/tests/configs/htex_local_intask_staging.py +5 -9
- parsl/tests/configs/htex_local_rsync_staging.py +4 -8
- parsl/tests/configs/local_radical.py +1 -3
- parsl/tests/configs/local_radical_mpi.py +2 -2
- parsl/tests/configs/local_threads_checkpoint_periodic.py +8 -10
- parsl/tests/configs/local_threads_monitoring.py +0 -1
- parsl/tests/configs/midway.py +2 -2
- parsl/tests/configs/nscc_singapore.py +3 -3
- parsl/tests/configs/osg_htex.py +1 -1
- parsl/tests/configs/petrelkube.py +3 -2
- parsl/tests/configs/slurm_local.py +24 -0
- parsl/tests/configs/summit.py +1 -0
- parsl/tests/configs/taskvine_ex.py +4 -7
- parsl/tests/configs/user_opts.py +2 -8
- parsl/tests/configs/workqueue_ex.py +4 -6
- parsl/tests/conftest.py +27 -13
- parsl/tests/integration/test_stress/test_python_simple.py +3 -4
- parsl/tests/integration/test_stress/test_python_threads.py +3 -5
- parsl/tests/manual_tests/htex_local.py +4 -6
- parsl/tests/manual_tests/test_basic.py +1 -0
- parsl/tests/manual_tests/test_log_filter.py +3 -1
- parsl/tests/manual_tests/test_memory_limits.py +6 -8
- parsl/tests/manual_tests/test_regression_220.py +2 -1
- parsl/tests/manual_tests/test_udp_simple.py +4 -4
- parsl/tests/manual_tests/test_worker_count.py +3 -2
- parsl/tests/scaling_tests/htex_local.py +2 -4
- parsl/tests/scaling_tests/test_scale.py +0 -9
- parsl/tests/scaling_tests/vineex_condor.py +1 -2
- parsl/tests/scaling_tests/vineex_local.py +1 -2
- parsl/tests/site_tests/site_config_selector.py +1 -6
- parsl/tests/site_tests/test_provider.py +4 -2
- parsl/tests/site_tests/test_site.py +2 -0
- parsl/tests/sites/test_affinity.py +7 -7
- parsl/tests/sites/test_dynamic_executor.py +3 -4
- parsl/tests/sites/test_ec2.py +3 -2
- parsl/tests/sites/test_worker_info.py +4 -5
- parsl/tests/test_aalst_patterns.py +0 -1
- parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
- parsl/tests/test_bash_apps/test_basic.py +10 -4
- parsl/tests/test_bash_apps/test_error_codes.py +5 -7
- parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
- parsl/tests/test_bash_apps/test_kwarg_storage.py +1 -1
- parsl/tests/test_bash_apps/test_memoize.py +2 -8
- parsl/tests/test_bash_apps/test_memoize_ignore_args.py +9 -14
- parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +9 -14
- parsl/tests/test_bash_apps/test_multiline.py +1 -1
- parsl/tests/test_bash_apps/test_pipeline.py +1 -1
- parsl/tests/test_bash_apps/test_std_uri.py +123 -0
- parsl/tests/test_bash_apps/test_stdout.py +33 -8
- parsl/tests/test_callables.py +2 -2
- parsl/tests/test_checkpointing/test_periodic.py +21 -39
- parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
- parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
- parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
- parsl/tests/test_checkpointing/test_regression_239.py +1 -1
- parsl/tests/test_checkpointing/test_task_exit.py +2 -3
- parsl/tests/test_docs/test_from_slides.py +5 -2
- parsl/tests/test_docs/test_kwargs.py +4 -1
- parsl/tests/test_docs/test_tutorial_1.py +1 -2
- parsl/tests/test_docs/test_workflow1.py +2 -2
- parsl/tests/test_docs/test_workflow2.py +0 -1
- parsl/tests/test_error_handling/test_rand_fail.py +2 -2
- parsl/tests/test_error_handling/test_resource_spec.py +10 -12
- parsl/tests/test_error_handling/test_retries.py +6 -16
- parsl/tests/test_error_handling/test_retry_handler.py +1 -0
- parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
- parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
- parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
- parsl/tests/test_execute_task.py +29 -0
- parsl/tests/test_flux.py +1 -1
- parsl/tests/test_htex/test_basic.py +2 -3
- parsl/tests/test_htex/test_block_manager_selector_unit.py +20 -0
- parsl/tests/test_htex/test_command_client_timeout.py +66 -0
- parsl/tests/test_htex/test_connected_blocks.py +3 -2
- parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
- parsl/tests/test_htex/test_disconnected_blocks.py +6 -5
- parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
- parsl/tests/test_htex/test_drain.py +79 -0
- parsl/tests/test_htex/test_htex.py +51 -25
- parsl/tests/test_htex/test_manager_failure.py +0 -1
- parsl/tests/test_htex/test_manager_selector_by_block.py +51 -0
- parsl/tests/test_htex/test_managers_command.py +36 -0
- parsl/tests/test_htex/test_missing_worker.py +2 -12
- parsl/tests/test_htex/test_multiple_disconnected_blocks.py +9 -9
- parsl/tests/test_htex/test_resource_spec_validation.py +45 -0
- parsl/tests/test_htex/test_zmq_binding.py +29 -8
- parsl/tests/test_monitoring/test_app_names.py +86 -0
- parsl/tests/test_monitoring/test_basic.py +73 -25
- parsl/tests/test_monitoring/test_db_locks.py +6 -4
- parsl/tests/test_monitoring/test_fuzz_zmq.py +19 -8
- parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +80 -0
- parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
- parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
- parsl/tests/test_monitoring/test_stdouterr.py +134 -0
- parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
- parsl/tests/test_mpi_apps/test_bad_mpi_config.py +33 -26
- parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +28 -11
- parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
- parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
- parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
- parsl/tests/test_mpi_apps/test_resource_spec.py +42 -49
- parsl/tests/test_providers/test_kubernetes_provider.py +102 -0
- parsl/tests/test_providers/test_local_provider.py +3 -132
- parsl/tests/test_providers/test_pbspro_template.py +2 -3
- parsl/tests/test_providers/test_slurm_template.py +2 -3
- parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
- parsl/tests/test_python_apps/test_context_manager.py +128 -0
- parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
- parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
- parsl/tests/test_python_apps/test_fail.py +0 -25
- parsl/tests/test_python_apps/test_futures.py +2 -1
- parsl/tests/test_python_apps/test_inputs_default.py +22 -0
- parsl/tests/test_python_apps/test_join.py +0 -1
- parsl/tests/test_python_apps/test_lifted.py +11 -7
- parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
- parsl/tests/test_python_apps/test_outputs.py +1 -1
- parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
- parsl/tests/test_radical/test_mpi_funcs.py +1 -2
- parsl/tests/test_regression/test_1480.py +2 -1
- parsl/tests/test_regression/test_1653.py +2 -1
- parsl/tests/test_regression/test_226.py +1 -0
- parsl/tests/test_regression/test_2652.py +1 -0
- parsl/tests/test_regression/test_69a.py +0 -1
- parsl/tests/test_regression/test_854.py +4 -2
- parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
- parsl/tests/test_regression/test_98.py +0 -1
- parsl/tests/test_scaling/test_block_error_handler.py +9 -4
- parsl/tests/test_scaling/test_regression_1621.py +11 -15
- parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +84 -0
- parsl/tests/test_scaling/test_regression_3696_oscillation.py +103 -0
- parsl/tests/test_scaling/test_scale_down.py +2 -5
- parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +6 -18
- parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +71 -0
- parsl/tests/test_scaling/test_shutdown_scalein.py +73 -0
- parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +90 -0
- parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
- parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
- parsl/tests/test_serialization/test_basic.py +2 -1
- parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
- parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
- parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
- parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
- parsl/tests/test_shutdown/test_kill_monitoring.py +64 -0
- parsl/tests/test_staging/staging_provider.py +2 -2
- parsl/tests/test_staging/test_1316.py +3 -4
- parsl/tests/test_staging/test_docs_1.py +2 -1
- parsl/tests/test_staging/test_docs_2.py +2 -1
- parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
- parsl/tests/{test_data → test_staging}/test_file.py +6 -6
- parsl/tests/{test_data → test_staging}/test_output_chain_filenames.py +3 -0
- parsl/tests/test_staging/test_staging_ftp.py +1 -0
- parsl/tests/test_staging/test_staging_https.py +5 -2
- parsl/tests/test_staging/test_staging_stdout.py +64 -0
- parsl/tests/test_staging/test_zip_in.py +39 -0
- parsl/tests/test_staging/test_zip_out.py +110 -0
- parsl/tests/test_staging/test_zip_to_zip.py +41 -0
- parsl/tests/test_summary.py +2 -2
- parsl/tests/test_thread_parallelism.py +0 -1
- parsl/tests/test_threads/test_configs.py +1 -2
- parsl/tests/test_threads/test_lazy_errors.py +2 -2
- parsl/tests/test_utils/test_execute_wait.py +35 -0
- parsl/tests/test_utils/test_sanitize_dns.py +76 -0
- parsl/tests/unit/test_address.py +20 -0
- parsl/tests/unit/test_file.py +99 -0
- parsl/tests/unit/test_usage_tracking.py +66 -0
- parsl/usage_tracking/api.py +65 -0
- parsl/usage_tracking/levels.py +6 -0
- parsl/usage_tracking/usage.py +104 -62
- parsl/utils.py +139 -6
- parsl/version.py +1 -1
- {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/exec_parsl_function.py +6 -5
- parsl-2025.1.13.data/scripts/interchange.py +649 -0
- {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/process_worker_pool.py +115 -77
- parsl-2025.1.13.dist-info/METADATA +96 -0
- parsl-2025.1.13.dist-info/RECORD +462 -0
- {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/WHEEL +1 -1
- parsl/channels/__init__.py +0 -7
- parsl/channels/base.py +0 -141
- parsl/channels/errors.py +0 -113
- parsl/channels/local/local.py +0 -164
- parsl/channels/oauth_ssh/oauth_ssh.py +0 -110
- parsl/channels/ssh/ssh.py +0 -276
- parsl/channels/ssh_il/__init__.py +0 -0
- parsl/channels/ssh_il/ssh_il.py +0 -74
- parsl/configs/ad_hoc.py +0 -35
- parsl/executors/radical/rpex_master.py +0 -42
- parsl/monitoring/radios.py +0 -175
- parsl/providers/ad_hoc/__init__.py +0 -0
- parsl/providers/ad_hoc/ad_hoc.py +0 -248
- parsl/providers/cobalt/__init__.py +0 -0
- parsl/providers/cobalt/cobalt.py +0 -236
- parsl/providers/cobalt/template.py +0 -17
- parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
- parsl/tests/configs/cooley_htex.py +0 -37
- parsl/tests/configs/htex_ad_hoc_cluster.py +0 -28
- parsl/tests/configs/local_adhoc.py +0 -18
- parsl/tests/configs/swan_htex.py +0 -43
- parsl/tests/configs/theta.py +0 -37
- parsl/tests/integration/test_channels/__init__.py +0 -0
- parsl/tests/integration/test_channels/test_channels.py +0 -17
- parsl/tests/integration/test_channels/test_local_channel.py +0 -42
- parsl/tests/integration/test_channels/test_scp_1.py +0 -45
- parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
- parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
- parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
- parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
- parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -48
- parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -88
- parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
- parsl/tests/sites/test_local_adhoc.py +0 -61
- parsl/tests/test_channels/__init__.py +0 -0
- parsl/tests/test_channels/test_large_output.py +0 -22
- parsl/tests/test_data/__init__.py +0 -0
- parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -51
- parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -16
- parsl-2024.3.11.dist-info/METADATA +0 -98
- parsl-2024.3.11.dist-info/RECORD +0 -447
- parsl/{channels/local → monitoring/radios}/__init__.py +0 -0
- parsl/{channels/oauth_ssh → tests/test_shutdown}/__init__.py +0 -0
- parsl/tests/{test_data → test_staging}/test_file_apps.py +0 -0
- parsl/tests/{test_data → test_staging}/test_file_staging.py +0 -0
- parsl/{channels/ssh → tests/unit}/__init__.py +0 -0
- {parsl-2024.3.11.data → parsl-2025.1.13.data}/scripts/parsl_coprocess.py +1 -1
- {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/LICENSE +0 -0
- {parsl-2024.3.11.dist-info → parsl-2025.1.13.dist-info}/entry_points.txt +0 -0
- {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 '
|
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.
|
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,12 +1,13 @@
|
|
1
1
|
"""Tests related to assigning workers to specific compute units"""
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
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()
|
parsl/tests/sites/test_ec2.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
"""Tests related to Parsl workers being able to access their worker ID"""
|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
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
|
),
|
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
@@ -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
|
-
|
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
|
-
|
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.
|
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
|
30
|
-
|
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
|
-
|
40
|
-
|
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
|
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.
|
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
|
-
|
39
|
+
no_checkpoint_stdout_app(stdout=str(path_x)).result()
|
40
|
+
path_x.unlink(missing_ok=False)
|
45
41
|
|
46
|
-
|
47
|
-
|
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.
|
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(
|
@@ -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.
|
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.
|
76
|
-
|
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
|
-
|
93
|
-
|
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
|