#! /bin/bash

# Some of the tests must be excluded for a variety of reasons.

# This script is called from both debian/rules and from the
# autopkgtest suite (both from our hand-crafted test script and from
# autopkgtest-pkg-pybuild), with the first argument being "rules"
# (for build-time and autopkgtest-pkg-pybuild) or "autopkgtest"
# (for our hand-crafted autopkgtest), and the second argument being
# the Python interpreter (eg python3.12) and returns an argument
# string that can then be passed to pytest.
# At present, we do not need to handle different Python versions, but
# this may be needed in future.

source=$1
interpreter=$2

case $source in
    rules)
        if [ -n "$AUTOPKGTEST_TMP" ]
        then
            mode=autopkgtest-pybuild
            arch=$(dpkg --print-architecture)
        else
            mode=build
            arch=$(dpkg-architecture -qDEB_HOST_ARCH)
        fi
        ;;
    autopkgtest)
        mode=autopkgtest-manual
        arch=$(dpkg --print-architecture)
        ;;
    *)
        echo "Unexpected mode for debian/get_test_exclusions: $mode" >&2
        echo "Giving up" >&2
        exit 1
        ;;
esac

EXCLUDES=(
    cli/tests/test_dask_scheduler.py::test_no_dashboard
    deploy/tests/test_local.py::test_localcluster_get_client
    deploy/tests/test_old_ssh.py::test_cluster
    deploy/tests/test_old_ssh.py::test_old_ssh_nprocs_renamed_to_n_workers
    deploy/tests/test_old_ssh.py::test_nprocs_attribute_is_deprecated
    deploy/tests/test_ssh.py::test_nprocs_attribute_is_deprecated
    http/tests/test_core.py::test_prometheus_api_doc
    tests/test_init.py::test_git_revision
    tests/test_jupyter.py::test_jupyter_idle_timeout
    tests/test_jupyter.py::test_jupyter_idle_timeout_returned
    tests/test_jupyter.py::test_jupyter_server
    tests/test_jupyter.py::test_shutsdown_cleanly
    tests/test_profile.py::test_stack_overflow
    tests/test_pubsub.py::test_client_worker
    tests/test_queues.py::test_queue_in_task
    tests/test_spill.py::test_spillbuffer_oserror
    tests/test_steal.py::test_steal_twice
    tests/test_utils_test.py::test_cluster
    tests/test_variable.py::test_variable_in_task
    tests/test_worker.py::test_process_executor_kills_process
    tests/test_worker_memory.py::test_fail_to_pickle_execute_1
    tests/test_worker_state_machine.py::test_task_state_instance_are_garbage_collected
)

IGNORES=()

# The following test item is pending resolution of [1].  Deeply
# nested structures may be generated with dask.distributed profiling
# code, and since python3.12, somehow the TypeError is not raised
# anymore.  Probable outcome will be a RecursionError, which may
# mismatch some expectations downstream.
#
# [1]: https://github.com/dask/distributed/issues/8700
EXCLUDES+=(
    protocol/tests/test_protocol.py::test_deeply_nested_structures
    protocol/tests/test_serialize.py::test_deeply_nested_structures
)

# armel and armhf crash on some tests for unknown reasons.  We skip
# these.
case $arch in
    armel)
        EXCLUDES+=(
            tests/test_steal.py::test_dont_steal_fast_tasks_compute_time
        )
        ;;
    armhf)
        EXCLUDES+=(
            deploy/tests/test_local.py::test_local_cluster_redundant_kwarg
            deploy/tests/test_slow_adaptive.py::test_adaptive
            tests/test_client.py::test_futures_in_subgraphs
            tests/test_dask_collections.py::test_dataframe_groupby_tasks
            tests/test_dask_collections.py::test_dataframes
            tests/test_dask_collections.py::test_rolling_sync
            tests/test_scheduler.py::test_balance_many_workers_2
            tests/test_scheduler.py::test_default_task_duration_splits
            tests/test_steal.py::test_blocklist_shuffle_split
        )
        ;;
esac

# Some cpu architectures are tripping on the following tests because they
# react too slowly for the expected timings; this includes riscv64, but also
# surprizingly s390x.  Issue is reproducible while running CPU emulation,
# which may also be an indicator of something else wrong.
case $arch in
    riscv64|s390x)
        EXCLUDES+=(
            tests/test_asyncprocess.py::test_exit_callback
            tests/test_asyncprocess.py::test_num_fds
            tests/test_chaos.py::test_KillWorker
            tests/test_nanny.py::test_nanny_process_failure
            tests/test_nanny.py::test_num_fds
            tests/test_priorities.py::test_last_in_first_out
            tests/test_steal.py::test_dont_steal_fast_tasks_compute_time
            tests/test_worker.py::test_missing_released_zombie_tasks_2
            tests/test_worker_state_machine.py::test_task_state_instance_are_garbage_collected
        )
        ;;
esac

# These tests need an Internet access to pass properly.  Use a
# build environment that properly hides the host's network card to
# capture newer such tests (e.g. chroot mode "unshare" or lxc).
# (Note that several of these test names are repeated in different test
# files, so it is possible that this is broader than needed.  These
# tests will be picked up by autopkgtest, though, so it is not much of
# an issue.)
case $mode in
    build|autopkgtest-pybuild)
        EXCLUDES+=(
            cli/tests/test_dask_scheduler.py::test_defaults
            cli/tests/test_dask_scheduler.py::test_hostport
            cli/tests/test_dask_spec.py::test_errors
            cli/tests/test_dask_worker.py::test_scheduler_file
            cli/tests/test_dask_worker.py::test_scheduler_file
            cli/tests/test_dask_worker.py::test_scheduler_file
            dashboard/tests/test_scheduler_bokeh.py::test_counters
            dashboard/tests/test_worker_bokeh.py::test_counters
            deploy/tests/test_local.py::test_adapt_then_manual
            deploy/tests/test_local.py::test_async_with
            deploy/tests/test_local.py::test_close_twice
            deploy/tests/test_local.py::test_cluster_info_sync
            deploy/tests/test_local.py::test_local_tls
            deploy/tests/test_local.py::test_no_dangling_asyncio_tasks
            deploy/tests/test_local.py::test_only_local_access
            deploy/tests/test_local.py::test_remote_access
            diagnostics/tests/test_progress_widgets.py::test_serializers
            diagnostics/tests/test_scheduler_plugin.py::test_lifecycle
            http/scheduler/tests/test_missing_bokeh.py::test_missing_bokeh
            http/scheduler/tests/test_scheduler_http.py::test_metrics_when_prometheus_client_not_installed
            protocol/tests/test_serialize.py::test_errors
            tests/test_batched.py::test_BatchedSend
            tests/test_batched.py::test_close_closed
            tests/test_batched.py::test_close_twice
            tests/test_batched.py::test_send_after_stream_start
            tests/test_batched.py::test_send_before_close
            tests/test_batched.py::test_send_before_start
            tests/test_batched.py::test_sending_traffic_jam
            tests/test_batched.py::test_serializers
            tests/test_client.py::TestClientSecurityLoader::test_security_loader
            tests/test_client.py::TestClientSecurityLoader::test_security_loader_ignored_if_explicit_security_provided
            tests/test_client.py::TestClientSecurityLoader::test_security_loader_ignored_if_returns_none
            tests/test_client.py::test_async_with
            tests/test_client.py::test_client_is_quiet_cluster_close
            tests/test_client.py::test_dashboard_link_cluster
            tests/test_client.py::test_dashboard_link_inproc
            tests/test_client.py::test_file_descriptors_dont_leak
            tests/test_client.py::test_mixing_clients_different_scheduler
            tests/test_client.py::test_quiet_client_close
            tests/test_client.py::test_rebalance_sync
            tests/test_client.py::test_repr_localcluster
            tests/test_client.py::test_security_loader
            tests/test_client.py::test_security_loader_ignored_if_explicit_security_provided
            tests/test_client.py::test_security_loader_ignored_if_returns_none
            tests/test_client.py::test_shutdown
            tests/test_client.py::test_shutdown_is_quiet_with_cluster
            tests/test_client.py::test_shutdown_localcluster
            tests/test_client.py::test_shutdown_stops_callbacks
            tests/test_client_loop.py::test_close_loop_sync_start_new_loop
            tests/test_client_loop.py::test_close_loop_sync_use_running_loop
            tests/test_core.py::test_close_fast_without_active_handlers
            tests/test_core.py::test_close_grace_period_for_handlers
            tests/test_core.py::test_close_properly
            tests/test_core.py::test_compression
            tests/test_core.py::test_connection_pool
            tests/test_core.py::test_connection_pool_close_while_connecting
            tests/test_core.py::test_connection_pool_detects_remote_close
            tests/test_core.py::test_connection_pool_outside_cancellation
            tests/test_core.py::test_connection_pool_remove
            tests/test_core.py::test_connection_pool_respects_limit
            tests/test_core.py::test_connection_pool_tls
            tests/test_core.py::test_counters
            tests/test_core.py::test_deserialize_error
            tests/test_core.py::test_errors
            tests/test_core.py::test_identity_inproc
            tests/test_core.py::test_identity_tcp
            tests/test_core.py::test_large_packets_inproc
            tests/test_core.py::test_messages_are_ordered_bsend
            tests/test_core.py::test_messages_are_ordered_raw
            tests/test_core.py::test_ports
            tests/test_core.py::test_rpc_default
            tests/test_core.py::test_rpc_inproc
            tests/test_core.py::test_rpc_message_lifetime_default
            tests/test_core.py::test_rpc_message_lifetime_inproc
            tests/test_core.py::test_rpc_message_lifetime_tcp
            tests/test_core.py::test_rpc_serialization
            tests/test_core.py::test_rpc_tcp
            tests/test_core.py::test_rpc_tls
            tests/test_core.py::test_rpc_with_many_connections_inproc
            tests/test_core.py::test_rpc_with_many_connections_tcp
            tests/test_core.py::test_send_recv_args
            tests/test_core.py::test_send_recv_cancelled
            tests/test_core.py::test_server
            tests/test_core.py::test_server_comms_mark_active_handlers
            tests/test_core.py::test_server_raises_on_blocked_handlers
            tests/test_jupyter.py::test_jupyter_idle_timeout
            tests/test_jupyter.py::test_jupyter_server
            tests/test_locks.py::test_errors
            tests/test_nanny.py::test_scheduler_file
            tests/test_nanny.py::test_scheduler_file
            tests/test_nanny.py::test_scheduler_file
            tests/test_nanny.py::test_worker_uses_same_host_as_nanny
            tests/test_preload.py::test_failure_doesnt_crash_scheduler
            tests/test_preload.py::test_preload_import_time
            tests/test_preload.py::test_preload_manager_sequence
            tests/test_preload.py::test_worker_preload_text
            tests/test_scheduler.py::test_allowed_failures_config
            tests/test_scheduler.py::test_async_context_manager
            tests/test_scheduler.py::test_dashboard_host
            tests/test_scheduler.py::test_file_descriptors_dont_leak
            tests/test_scheduler.py::test_finished
            tests/test_scheduler.py::test_multiple_listeners
            tests/test_scheduler.py::test_no_dangling_asyncio_tasks
            tests/test_scheduler.py::test_scheduler_file
            tests/test_scheduler.py::test_scheduler_file
            tests/test_scheduler.py::test_scheduler_file
            tests/test_security.py::test_require_encryption
            tests/test_security.py::test_tls_listen_connect
            tests/test_security.py::test_tls_temporary_credentials_functional
            tests/test_semaphore.py::test_threadpoolworkers_pick_correct_ioloop
            tests/test_tls_functional.py::test_security_dict_input_no_security
            tests/test_utils_test.py::test_ensure_no_new_clients
            tests/test_utils_test.py::test_freeze_batched_send
            tests/test_utils_test.py::test_locked_comm_drop_in_replacement
            tests/test_utils_test.py::test_locked_comm_intercept_read
            tests/test_utils_test.py::test_locked_comm_intercept_write
            tests/test_worker.py::test_host_uses_scheduler_protocol
            tests/test_worker.py::test_plugin_exception
            tests/test_worker.py::test_plugin_internal_exception
            tests/test_worker.py::test_plugin_multiple_exceptions
            tests/test_worker.py::test_scheduler_file
            tests/test_worker.py::test_scheduler_file
            tests/test_worker.py::test_scheduler_file
            tests/test_worker_client.py::test_dont_override_default_get
        )

        # The preamble of these files requires internet access, so
        # we have to ignore the whole file.
        IGNORES+=(
            comm/tests/test_comms.py
            comm/tests/test_ws.py
        )
        # Many or most of the tests in these files require internet access;
        # rather than list them explicity, we ignore the whole file
        # when we don't have internet access.
        IGNORES+=(
            deploy/tests/test_adaptive.py
            deploy/tests/test_local.py
            deploy/tests/test_slow_adaptive.py
            deploy/tests/test_spec_cluster.py
        )
        ;;
esac

# Some tests require the package to be installed, so we do not run them
# at build time.
case $mode in
    build)
        EXCLUDES+=(
            cli/tests/test_dask_scheduler.py::test_dashboard
            cli/tests/test_dask_scheduler.py::test_dashboard_allowlist
            cli/tests/test_dask_scheduler.py::test_dashboard_non_standard_ports
            cli/tests/test_dask_scheduler.py::test_dashboard_port_zero
            cli/tests/test_dask_scheduler.py::test_defaults
            cli/tests/test_dask_scheduler.py::test_hostport
            cli/tests/test_dask_scheduler.py::test_multiple_protocols
            cli/tests/test_dask_scheduler.py::test_multiple_workers
            cli/tests/test_dask_scheduler.py::test_multiple_workers_2
            cli/tests/test_dask_scheduler.py::test_preload_command
            cli/tests/test_dask_scheduler.py::test_preload_command_default
            cli/tests/test_dask_scheduler.py::test_preload_config
            cli/tests/test_dask_scheduler.py::test_preload_file
            cli/tests/test_dask_scheduler.py::test_preload_module
            cli/tests/test_dask_scheduler.py::test_preload_remote_module
            cli/tests/test_dask_scheduler.py::test_scheduler_port_zero
            cli/tests/test_dask_scheduler.py::test_single_executable_deprecated
            cli/tests/test_dask_worker.py::test_contact_listen_address
            cli/tests/test_dask_worker.py::test_dashboard_non_standard_ports
            cli/tests/test_dask_worker.py::test_error_during_startup
            cli/tests/test_dask_worker.py::test_integer_names
            cli/tests/test_dask_worker.py::test_listen_address_ipv6
            cli/tests/test_dask_worker.py::test_local_directory
            cli/tests/test_dask_worker.py::test_memory_limit
            cli/tests/test_dask_worker.py::test_nanny_worker_port_range
            cli/tests/test_dask_worker.py::test_nanny_worker_port_range_too_many_workers_raises
            cli/tests/test_dask_worker.py::test_nanny_worker_ports
            cli/tests/test_dask_worker.py::test_no_nanny
            cli/tests/test_dask_worker.py::test_nworkers_auto
            cli/tests/test_dask_worker.py::test_nworkers_expands_name
            cli/tests/test_dask_worker.py::test_nworkers_negative
            cli/tests/test_dask_worker.py::test_nworkers_requires_nanny
            cli/tests/test_dask_worker.py::test_preload_config
            cli/tests/test_dask_worker.py::test_resources
            cli/tests/test_dask_worker.py::test_respect_host_listen_address
            cli/tests/test_dask_worker.py::test_scheduler_address_env
            cli/tests/test_dask_worker.py::test_scheduler_file
            cli/tests/test_dask_worker.py::test_set_lifetime_restart_via_env_var
            cli/tests/test_dask_worker.py::test_set_lifetime_stagger_via_env_var
            cli/tests/test_dask_worker.py::test_signal_handling
            cli/tests/test_dask_worker.py::test_single_executable_deprecated
            cli/tests/test_dask_worker.py::test_single_executable_works
            cli/tests/test_dask_worker.py::test_timeout
            cli/tests/test_dask_worker.py::test_worker_class
            tests/test_config.py::test_logging_extended
            tests/test_config.py::test_logging_file_config
            tests/test_config.py::test_logging_mutual_exclusive
            tests/test_config.py::test_logging_simple
            tests/test_config.py::test_logging_simple_under_distributed
            tests/test_queues.py::test_queue_in_task
            tests/test_variable.py::test_variable_in_task
        )
        ;;
esac

# Print the list of excluded tests for pytest; during build, this
# requires a "distributed/" prefix on all test names, but for the
# installed version during autopkgtests, it does not.
case $mode in
    build)
        ignoreprefix="distributed/"
        excludeprefix="distributed/"
        ;;
    autopkgtest-manual)
        # See https://github.com/pytest-dev/pytest/issues/3287
	# The rootdir is /tmp/autopkgtest-*/downtmp/autopkgtest_tmp
        ignoreprefix="../../../../usr/lib/python3/dist-packages/distributed/"
        excludeprefix=""
	;;
    autopkgtest-pybuild)
	# The rootdir path has a different depth in the pybuild autopkgtest:
	# /tmp/autopkgtest-*/downtmp/autopkgtest_tmp/build
        ignoreprefix="../../../../../usr/lib/python3/dist-packages/distributed/"
        excludeprefix=""
        ;;
esac

for test in "${IGNORES[@]}"
do
    printf "%s" "--ignore=$ignoreprefix$test "
done
for test in "${EXCLUDES[@]}"
do
    printf "%s" "--deselect=$excludeprefix$test "
done
