rucio-clients 32.6.0__tar.gz → 33.0.0__tar.gz
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.
Potentially problematic release.
This version of rucio-clients might be problematic. Click here for more details.
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/PKG-INFO +7 -7
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/alembicrevision.py +1 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/didclient.py +0 -13
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/gfal.py +1 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/rclone.py +1 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/srm.py +1 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/ssh.py +1 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/xrootd.py +1 -1
- rucio-clients-33.0.0/lib/rucio/vcsversion.py +11 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/requirements.txt +26 -26
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_conveyor.py +16 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_conveyor_submitter.py +9 -2
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_daemons.py +1 -2
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_oidc.py +31 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_request.py +86 -1
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_transfer.py +33 -1
- rucio-clients-32.6.0/lib/rucio/vcsversion.py +0 -11
- rucio-clients-32.6.0/tests/test_temporary_did.py +0 -74
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/AUTHORS.rst +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/ChangeLog +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/LICENSE +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/MANIFEST.in +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/README.rst +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/bin/rucio +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/bin/rucio-admin +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/etc/rucio.cfg.template +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/accountclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/baseclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/client.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/configclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/downloadclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/importclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/metaclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/rseclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/client/uploadclient.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/cache.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/config.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/constants.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/constraints.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/didtype.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/exception.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/extra.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/logging.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/pcache.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/policy.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/atlas.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/belleii.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/cms.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/domatpc.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/escape.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/icecube.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/schema/lsst.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/types.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/common/utils.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/gsiftp.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/protocols/webdav.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/lib/rucio/version.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/pylintrc +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/pyproject.toml +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/setup.cfg +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/setup.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/setuputil.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_abacus_account.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_abacus_rse.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_account.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_account_limits.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_api_external_representation.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_archive.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_auditor.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_authentication.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_automatix.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_bad_replica.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_bb8.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_belleii.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_bin_rucio.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_boolean.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_clients.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_common_types.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_config.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_counter.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_credential.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_curl.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_dataset_replicas.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_db.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_did.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_didtype.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_download.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_dumper.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_dumper_consistency.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_dumper_data_model.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_dumper_path_parsing.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_filter_engine.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_heartbeat.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_hermes.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_identity.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_impl_upload_download.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_import_export.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_judge_cleaner.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_judge_evaluator.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_judge_injector.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_judge_repairer.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_lifetime.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_message.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_meta.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_meta_did.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_module_import.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_monitor.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_multi_vo.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_naming_convention.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_oauthmanager.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_permission.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_pfns.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_ping.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_preparer.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_qos.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_quarantined_replica.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_reaper.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_redirect.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_replica.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_replica_recoverer.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_replica_sorting.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_root_proxy.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_lfn2path.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rse_selector.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rucio_server.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_rule.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_schema_cms.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_scope.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_subscription.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_throttler.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_tpc.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_trace.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_undertaker.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_upload.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tests/test_utils.py +0 -0
- {rucio-clients-32.6.0 → rucio-clients-33.0.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rucio-clients
|
|
3
|
-
Version:
|
|
3
|
+
Version: 33.0.0
|
|
4
4
|
Summary: Rucio Client Lite Package
|
|
5
5
|
Home-page: https://rucio.cern.ch/
|
|
6
6
|
Author: Rucio
|
|
@@ -20,21 +20,21 @@ Requires-Python: >=3.9, <4
|
|
|
20
20
|
License-File: LICENSE
|
|
21
21
|
License-File: AUTHORS.rst
|
|
22
22
|
Requires-Dist: requests<=2.31.0,>=2.25.1
|
|
23
|
-
Requires-Dist: urllib3~=1.26.
|
|
23
|
+
Requires-Dist: urllib3~=1.26.18
|
|
24
24
|
Requires-Dist: dogpile.cache~=1.2.2
|
|
25
25
|
Requires-Dist: tabulate~=0.9.0
|
|
26
|
-
Requires-Dist: jsonschema~=4.
|
|
26
|
+
Requires-Dist: jsonschema~=4.20.0
|
|
27
27
|
Provides-Extra: ssh
|
|
28
|
-
Requires-Dist: paramiko~=3.
|
|
28
|
+
Requires-Dist: paramiko~=3.3.1; extra == "ssh"
|
|
29
29
|
Provides-Extra: kerberos
|
|
30
30
|
Requires-Dist: kerberos~=1.3.1; extra == "kerberos"
|
|
31
31
|
Requires-Dist: pykerberos~=1.2.4; extra == "kerberos"
|
|
32
32
|
Requires-Dist: requests-kerberos>=0.14.0; extra == "kerberos"
|
|
33
33
|
Provides-Extra: swift
|
|
34
|
-
Requires-Dist: python-swiftclient~=4.
|
|
34
|
+
Requires-Dist: python-swiftclient~=4.4.0; extra == "swift"
|
|
35
35
|
Provides-Extra: argcomplete
|
|
36
|
-
Requires-Dist: argcomplete~=3.1.
|
|
36
|
+
Requires-Dist: argcomplete~=3.1.6; extra == "argcomplete"
|
|
37
37
|
Provides-Extra: sftp
|
|
38
|
-
Requires-Dist: paramiko~=3.
|
|
38
|
+
Requires-Dist: paramiko~=3.3.1; extra == "sftp"
|
|
39
39
|
Provides-Extra: dumper
|
|
40
40
|
Requires-Dist: python-magic~=0.4.27; extra == "dumper"
|
|
@@ -661,19 +661,6 @@ class DIDClient(BaseClient):
|
|
|
661
661
|
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
662
662
|
raise exc_cls(exc_msg)
|
|
663
663
|
|
|
664
|
-
def add_temporary_dids(self, dids):
|
|
665
|
-
"""
|
|
666
|
-
Bulk add temporary data identifiers.
|
|
667
|
-
|
|
668
|
-
:param dids: A list of dids.
|
|
669
|
-
"""
|
|
670
|
-
url = build_url(choice(self.list_hosts), path='tmp_dids')
|
|
671
|
-
r = self._send_request(url, type_='POST', data=dumps(dids))
|
|
672
|
-
if r.status_code == codes.created:
|
|
673
|
-
return True
|
|
674
|
-
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
675
|
-
raise exc_cls(exc_msg)
|
|
676
|
-
|
|
677
664
|
def list_archive_content(self, scope, name):
|
|
678
665
|
"""
|
|
679
666
|
List archive contents.
|
|
@@ -242,7 +242,7 @@ class Default(protocol.RSEProtocol):
|
|
|
242
242
|
if not prefix.endswith('/'):
|
|
243
243
|
prefix = ''.join([prefix, '/'])
|
|
244
244
|
|
|
245
|
-
lfns = [lfns] if
|
|
245
|
+
lfns = [lfns] if isinstance(lfns, dict) else lfns
|
|
246
246
|
for lfn in lfns:
|
|
247
247
|
scope, name = lfn['scope'], lfn['name']
|
|
248
248
|
if 'path' in lfn and lfn['path'] is not None:
|
|
@@ -51,7 +51,7 @@ class Default(protocol.RSEProtocol):
|
|
|
51
51
|
if '://' in hostname:
|
|
52
52
|
hostname = hostname.split("://")[1]
|
|
53
53
|
|
|
54
|
-
lfns = [lfns] if
|
|
54
|
+
lfns = [lfns] if isinstance(lfns, dict) else lfns
|
|
55
55
|
if not self.attributes['port']:
|
|
56
56
|
for lfn in lfns:
|
|
57
57
|
scope, name, path = lfn['scope'], lfn['name'], lfn.get('path')
|
|
@@ -157,7 +157,7 @@ class Default(protocol.RSEProtocol):
|
|
|
157
157
|
if not prefix.endswith('/'):
|
|
158
158
|
prefix = ''.join([prefix, '/'])
|
|
159
159
|
|
|
160
|
-
lfns = [lfns] if
|
|
160
|
+
lfns = [lfns] if isinstance(lfns, dict) else lfns
|
|
161
161
|
for lfn in lfns:
|
|
162
162
|
scope, name = lfn['scope'], lfn['name']
|
|
163
163
|
if 'path' in lfn and lfn['path'] is not None:
|
|
@@ -160,7 +160,7 @@ class Default(protocol.RSEProtocol):
|
|
|
160
160
|
if not prefix.endswith('/'):
|
|
161
161
|
prefix = ''.join([prefix, '/'])
|
|
162
162
|
|
|
163
|
-
lfns = [lfns] if
|
|
163
|
+
lfns = [lfns] if isinstance(lfns, dict) else lfns
|
|
164
164
|
for lfn in lfns:
|
|
165
165
|
scope, name = lfn['scope'], lfn['name']
|
|
166
166
|
if 'path' in lfn and lfn['path'] is not None:
|
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
# All dependencies needed to run rucio client (and server/daemons) should be defined here
|
|
2
2
|
requests>=2.25.1,<=2.31.0 # Python HTTP for Humans.
|
|
3
|
-
urllib3~=1.26.
|
|
3
|
+
urllib3~=1.26.18 # HTTP library with thread-safe connection pooling, file post, etc.
|
|
4
4
|
dogpile.cache~=1.2.2 # Caching API plugins (1.1.2 is the first version to support pymemcache)
|
|
5
5
|
tabulate~=0.9.0 # Pretty-print tabular data
|
|
6
|
-
jsonschema~=4.
|
|
6
|
+
jsonschema~=4.20.0 # For JSON schema validation (Policy modules)
|
|
7
7
|
|
|
8
8
|
# All dependencies needed in extras for rucio client (and server/daemons) should be defined here
|
|
9
|
-
paramiko~=3.
|
|
9
|
+
paramiko~=3.3.1 # ssh_extras; SSH2 protocol library (also needed in the server)
|
|
10
10
|
kerberos~=1.3.1 # kerberos_extras for client and server
|
|
11
11
|
pykerberos~=1.2.4 # kerberos_extras for client and server
|
|
12
12
|
requests-kerberos>=0.14.0 # kerberos_extras for client and server
|
|
13
|
-
python-swiftclient~=4.
|
|
14
|
-
argcomplete~=3.1.
|
|
13
|
+
python-swiftclient~=4.4.0 # swift_extras
|
|
14
|
+
argcomplete~=3.1.6 # argcomplete_extras; Bash tab completion for argparse
|
|
15
15
|
python-magic~=0.4.27 # dumper_extras; File type identification using libmagic
|
|
16
16
|
|
|
17
17
|
# All dependencies needed to run rucio server/daemons should be defined here
|
|
18
|
-
SQLAlchemy==2.0.
|
|
19
|
-
alembic~=1.
|
|
18
|
+
SQLAlchemy==2.0.23 # DB backend
|
|
19
|
+
alembic~=1.12.1 # Lightweight database migration tool for SQLAlchemy
|
|
20
20
|
pymemcache==4.0.0 # A comprehensive, fast, pure-Python memcached client (Used by Dogpile)
|
|
21
21
|
python-dateutil==2.8.2 # Extensions to the standard datetime module
|
|
22
22
|
stomp.py==8.1.0 # ActiveMQ Messaging Protocol
|
|
23
23
|
statsd==4.0.1 # Needed to log into graphite with more than 1 Hz
|
|
24
24
|
geoip2==4.7.0 # GeoIP2 API (for IPv6 support)
|
|
25
|
-
google-auth==2.
|
|
26
|
-
redis==
|
|
27
|
-
Flask==
|
|
25
|
+
google-auth==2.23.4 # Google authentication library for Python
|
|
26
|
+
redis==5.0.1 # Python client for Redis key-value store
|
|
27
|
+
Flask==3.0.0 # Python web framework
|
|
28
28
|
oic==1.6.1 # for authentication via OpenID Connect protocol
|
|
29
|
-
prometheus_client==0.
|
|
30
|
-
boto3==1.
|
|
29
|
+
prometheus_client==0.19.0 # Python client for the Prometheus monitoring system
|
|
30
|
+
boto3==1.29.5 # S3 boto protocol (new version)
|
|
31
31
|
|
|
32
32
|
# All dependencies needed in extras for rucio server/daemons should be defined here
|
|
33
33
|
cx_oracle==8.3.0 # oracle_extras
|
|
34
|
-
psycopg2-binary==2.9.
|
|
34
|
+
psycopg2-binary==2.9.9 # postgresql_extras
|
|
35
35
|
PyMySQL==1.1.0 # mysql_extras
|
|
36
36
|
PyYAML==6.0.1 # globus_extras and used for reading test configuration files
|
|
37
|
-
globus-sdk==3.
|
|
38
|
-
python3-saml==1.
|
|
39
|
-
pymongo==4.
|
|
37
|
+
globus-sdk==3.32.0 # globus_extras
|
|
38
|
+
python3-saml==1.16.0 # saml_extras
|
|
39
|
+
pymongo==4.6.0 # pymongo (metadata plugin)
|
|
40
40
|
|
|
41
41
|
# All dependencies needed to develop/test rucio should be defined here
|
|
42
|
-
pytest==7.4.
|
|
43
|
-
pytest-xdist~=3.
|
|
44
|
-
pyflakes==3.0
|
|
45
|
-
flake8==6.
|
|
46
|
-
pycodestyle==2.
|
|
47
|
-
pylint==3.0.
|
|
48
|
-
astroid==3.0.
|
|
49
|
-
virtualenv==20.24.
|
|
42
|
+
pytest==7.4.3
|
|
43
|
+
pytest-xdist~=3.5.0 # Used for parallel testing
|
|
44
|
+
pyflakes==3.1.0 # Passive checker of Python programs
|
|
45
|
+
flake8==6.1.0 # Wrapper around PyFlakes&pep8; python_version < '3.9'
|
|
46
|
+
pycodestyle==2.11.0 # New package replacing pep8; python_version < '3.9'
|
|
47
|
+
pylint==3.0.2
|
|
48
|
+
astroid==3.0.1
|
|
49
|
+
virtualenv==20.24.7 # Virtual Python Environment builder
|
|
50
50
|
xmltodict==0.13.0 # Makes working with XML feel like you are working with JSON
|
|
51
|
-
pytz==2023.3
|
|
51
|
+
pytz==2023.3.post1 # World timezone definitions, modern and historical
|
|
52
52
|
pydoc-markdown~=4.8.2 # Used for generating Markdown documentation for docusaurus
|
|
53
|
-
sh~=2.0.
|
|
53
|
+
sh~=2.0.6 # Convenience library for running subprocesses in Python
|
|
54
54
|
apispec==6.3.0 # Generate OpenApi definition out of pydoc comments
|
|
55
55
|
apispec-webframeworks # Integration of apispec in Flask
|
|
@@ -1364,7 +1364,10 @@ def test_multi_vo_certificates(file_config_mock, rse_factory, did_factory, scope
|
|
|
1364
1364
|
'rucio.core.config.REGION',
|
|
1365
1365
|
'rucio.daemons.reaper.reaper.REGION',
|
|
1366
1366
|
]}], indirect=True)
|
|
1367
|
-
|
|
1367
|
+
@pytest.mark.parametrize("file_config_mock", [{"overrides": [
|
|
1368
|
+
('transfers', 'stats_enabled', 'True'),
|
|
1369
|
+
]}], indirect=True)
|
|
1370
|
+
def test_two_multihops_same_intermediate_rse(rse_factory, did_factory, root_account, file_config_mock, core_config_mock, caches_mock):
|
|
1368
1371
|
"""
|
|
1369
1372
|
Handle correctly two multihop transfers having to both jump via the same intermediate hops
|
|
1370
1373
|
"""
|
|
@@ -1379,6 +1382,7 @@ def test_two_multihops_same_intermediate_rse(rse_factory, did_factory, root_acco
|
|
|
1379
1382
|
# +------>| RSE6 +--->| RSE7 |
|
|
1380
1383
|
# | | | |
|
|
1381
1384
|
# +------+ +------+
|
|
1385
|
+
start_time = datetime.utcnow()
|
|
1382
1386
|
_, _, reaper_cache_region = caches_mock
|
|
1383
1387
|
rse1, rse1_id = rse_factory.make_rse(scheme='mock', protocol_impl='rucio.rse.protocols.posix.Default')
|
|
1384
1388
|
rse2, rse2_id = rse_factory.make_rse(scheme='mock', protocol_impl='rucio.rse.protocols.posix.Default')
|
|
@@ -1465,6 +1469,17 @@ def test_two_multihops_same_intermediate_rse(rse_factory, did_factory, root_acco
|
|
|
1465
1469
|
with pytest.raises(ReplicaNotFound):
|
|
1466
1470
|
replica_core.get_replica(rse_id=rse_id, **did)
|
|
1467
1471
|
|
|
1472
|
+
# Verify that the statistics are correctly recorded for executed transfers
|
|
1473
|
+
stats_manager = request_core.TransferStatsManager()
|
|
1474
|
+
dict_stats = {}
|
|
1475
|
+
for stat in stats_manager.load_totals(
|
|
1476
|
+
older_t=start_time - stats_manager.raw_resolution
|
|
1477
|
+
):
|
|
1478
|
+
dict_stats.setdefault(stat['dest_rse_id'], {})[stat['src_rse_id']] = stat
|
|
1479
|
+
assert dict_stats[rse2_id][rse1_id]['files_failed'] == 1
|
|
1480
|
+
assert dict_stats[rse2_id][rse1_id]['files_done'] == 1
|
|
1481
|
+
assert dict_stats[rse2_id][rse1_id]['bytes_done'] == 2
|
|
1482
|
+
|
|
1468
1483
|
|
|
1469
1484
|
@skip_rse_tests_with_accounts
|
|
1470
1485
|
@pytest.mark.noparallel(groups=[NoParallelGroups.SUBMITTER, NoParallelGroups.POLLER])
|
|
@@ -283,7 +283,11 @@ def test_ignore_availability(rse_factory, did_factory, root_account, caches_mock
|
|
|
283
283
|
|
|
284
284
|
|
|
285
285
|
@pytest.mark.noparallel(reason="multiple submitters cannot be run in parallel due to partial job assignment by hash")
|
|
286
|
-
|
|
286
|
+
@pytest.mark.parametrize("file_config_mock", [
|
|
287
|
+
{"overrides": [('transfers', 'source_ranking_strategies', 'SkipSchemeMissmatch,PathDistance')]},
|
|
288
|
+
{"overrides": [('transfers', 'source_ranking_strategies', 'PathDistance')]}
|
|
289
|
+
], indirect=True)
|
|
290
|
+
def test_scheme_missmatch(rse_factory, did_factory, root_account, file_config_mock):
|
|
287
291
|
"""
|
|
288
292
|
Ensure that the requests are marked MISSMATCH_SCHEME when there is a path, but with wrong schemes.
|
|
289
293
|
"""
|
|
@@ -298,7 +302,10 @@ def test_scheme_missmatch(rse_factory, did_factory, root_account):
|
|
|
298
302
|
submitter(once=True, rses=[{'id': rse_id} for rse_id in (src_rse_id, dst_rse_id)], partition_wait_time=None, transfertools=['mock'], transfertype='single')
|
|
299
303
|
|
|
300
304
|
request = request_core.get_request_by_did(rse_id=dst_rse_id, **did)
|
|
301
|
-
|
|
305
|
+
if 'SkipSchemeMissmatch' in file_config_mock.get('transfers', 'source_ranking_strategies'):
|
|
306
|
+
assert request['state'] == RequestState.MISMATCH_SCHEME
|
|
307
|
+
else:
|
|
308
|
+
assert request['state'] == RequestState.NO_SOURCES
|
|
302
309
|
|
|
303
310
|
|
|
304
311
|
@pytest.mark.noparallel(groups=[NoParallelGroups.SUBMITTER])
|
|
@@ -30,7 +30,7 @@ from rucio.daemons.follower import follower
|
|
|
30
30
|
from rucio.daemons.hermes import hermes
|
|
31
31
|
from rucio.daemons.judge import cleaner, evaluator, injector, repairer
|
|
32
32
|
from rucio.daemons.oauthmanager import oauthmanager
|
|
33
|
-
from rucio.daemons.reaper import dark_reaper,
|
|
33
|
+
from rucio.daemons.reaper import dark_reaper, reaper
|
|
34
34
|
from rucio.daemons.replicarecoverer import suspicious_replica_recoverer
|
|
35
35
|
from rucio.daemons.tracer import kronos
|
|
36
36
|
from rucio.daemons.transmogrifier import transmogrifier
|
|
@@ -62,7 +62,6 @@ DAEMONS = [
|
|
|
62
62
|
repairer,
|
|
63
63
|
oauthmanager,
|
|
64
64
|
dark_reaper,
|
|
65
|
-
light_reaper,
|
|
66
65
|
reaper,
|
|
67
66
|
suspicious_replica_recoverer,
|
|
68
67
|
kronos,
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
|
|
16
16
|
import time
|
|
17
17
|
import traceback
|
|
18
|
+
import uuid
|
|
18
19
|
from datetime import datetime, timedelta
|
|
19
20
|
from unittest.mock import MagicMock, patch
|
|
20
21
|
from urllib.parse import urlparse, parse_qs
|
|
21
22
|
|
|
22
23
|
import pytest
|
|
24
|
+
from jwkest.jwt import JWT
|
|
23
25
|
from oic import rndstr
|
|
24
26
|
|
|
25
27
|
from rucio.common.config import config_get_bool
|
|
@@ -30,7 +32,8 @@ from rucio.core.account import add_account
|
|
|
30
32
|
from rucio.core.authentication import redirect_auth_oidc, validate_auth_token
|
|
31
33
|
from rucio.core.identity import add_account_identity
|
|
32
34
|
from rucio.core.oidc import (get_auth_oidc, get_token_oidc, get_token_for_account_operation,
|
|
33
|
-
EXPECTED_OIDC_AUDIENCE, EXPECTED_OIDC_SCOPE, oidc_identity_string
|
|
35
|
+
EXPECTED_OIDC_AUDIENCE, EXPECTED_OIDC_SCOPE, oidc_identity_string,
|
|
36
|
+
_token_cache_get, _token_cache_set)
|
|
34
37
|
from rucio.db.sqla import models
|
|
35
38
|
from rucio.db.sqla.constants import AccountType
|
|
36
39
|
from rucio.db.sqla.constants import IdentityType
|
|
@@ -1956,3 +1959,30 @@ class TestAuthCoreAPIoidc:
|
|
|
1956
1959
|
# ---------------------------
|
|
1957
1960
|
# Check if NO token has been received
|
|
1958
1961
|
assert not new_token_dict
|
|
1962
|
+
|
|
1963
|
+
|
|
1964
|
+
def test_token_cache() -> None:
|
|
1965
|
+
KEY = str(uuid.uuid1())
|
|
1966
|
+
assert _token_cache_get(KEY) is None
|
|
1967
|
+
|
|
1968
|
+
valid_token = JWT().pack([{
|
|
1969
|
+
'exp': int((datetime.utcnow() + timedelta(hours=1)).timestamp())
|
|
1970
|
+
}])
|
|
1971
|
+
_token_cache_set(KEY, valid_token)
|
|
1972
|
+
assert _token_cache_get(KEY) == valid_token
|
|
1973
|
+
|
|
1974
|
+
invalid_token = 'invalid'
|
|
1975
|
+
_token_cache_set(KEY, invalid_token)
|
|
1976
|
+
assert _token_cache_get(KEY) is None
|
|
1977
|
+
|
|
1978
|
+
below_min_lifetime_token = JWT().pack([{
|
|
1979
|
+
'exp': int((datetime.utcnow() + timedelta(minutes=1)).timestamp())
|
|
1980
|
+
}])
|
|
1981
|
+
_token_cache_set(KEY, below_min_lifetime_token)
|
|
1982
|
+
assert _token_cache_get(KEY) is None
|
|
1983
|
+
|
|
1984
|
+
expired_token = JWT().pack([{
|
|
1985
|
+
'exp': int((datetime.utcnow() - timedelta(minutes=1)).timestamp())
|
|
1986
|
+
}])
|
|
1987
|
+
_token_cache_set(KEY, expired_token)
|
|
1988
|
+
assert _token_cache_get(KEY) is None
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import json
|
|
16
17
|
from datetime import datetime
|
|
17
18
|
from typing import Union
|
|
18
19
|
|
|
@@ -20,8 +21,9 @@ import pytest
|
|
|
20
21
|
|
|
21
22
|
from rucio.common.config import config_get_bool
|
|
22
23
|
from rucio.common.utils import generate_uuid, parse_response
|
|
24
|
+
from rucio.core.distance import add_distance
|
|
23
25
|
from rucio.core.replica import add_replica
|
|
24
|
-
from rucio.core.request import queue_requests, get_request_by_did, list_requests, list_requests_history, set_transfer_limit
|
|
26
|
+
from rucio.core.request import queue_requests, get_request_by_did, list_requests, list_requests_history, set_transfer_limit, TransferStatsManager
|
|
25
27
|
from rucio.core.rse import add_rse_attribute
|
|
26
28
|
from rucio.db.sqla import models, constants
|
|
27
29
|
from rucio.db.sqla.constants import RequestType, RequestState
|
|
@@ -286,3 +288,86 @@ def test_api_list(
|
|
|
286
288
|
|
|
287
289
|
params = {'request_states': 'S', 'src_site': source_site, 'dst_site': 'unknown'}
|
|
288
290
|
check_error_api(params, 'NotFound', 'Could not resolve site name unknown to RSE', 404)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@pytest.mark.parametrize("file_config_mock", [{"overrides": [
|
|
294
|
+
('transfers', 'stats_enabled', 'True'),
|
|
295
|
+
]}], indirect=True)
|
|
296
|
+
def test_api_metrics(vo, rest_client, auth_token, rse_factory, did_factory, root_account, file_config_mock):
|
|
297
|
+
|
|
298
|
+
src_rse, src_rse_id = rse_factory.make_mock_rse()
|
|
299
|
+
dst_rse, dst_rse_id = rse_factory.make_mock_rse()
|
|
300
|
+
add_distance(src_rse_id, dst_rse_id, distance=10)
|
|
301
|
+
|
|
302
|
+
replica_bytes = 20
|
|
303
|
+
|
|
304
|
+
did1 = did_factory.random_file_did()
|
|
305
|
+
activity1 = 'User Subscription'
|
|
306
|
+
add_replica(rse_id=src_rse_id, bytes_=replica_bytes, adler32='beefdead', account=root_account, **did1)
|
|
307
|
+
|
|
308
|
+
did2 = did_factory.random_file_did()
|
|
309
|
+
activity2 = 'Test'
|
|
310
|
+
add_replica(rse_id=src_rse_id, bytes_=replica_bytes, adler32='beefdead', account=root_account, **did2)
|
|
311
|
+
|
|
312
|
+
requests = [
|
|
313
|
+
{
|
|
314
|
+
'dest_rse_id': dst_rse_id,
|
|
315
|
+
'source_rse_id': src_rse_id,
|
|
316
|
+
'request_type': RequestType.TRANSFER,
|
|
317
|
+
'request_id': generate_uuid(),
|
|
318
|
+
'name': did1['name'],
|
|
319
|
+
'scope': did1['scope'],
|
|
320
|
+
'rule_id': generate_uuid(),
|
|
321
|
+
'retry_count': 1,
|
|
322
|
+
'attributes': {
|
|
323
|
+
'activity': activity,
|
|
324
|
+
'bytes': replica_bytes,
|
|
325
|
+
'md5': '',
|
|
326
|
+
'adler32': ''
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
for did, activity in ((did1, activity1), (did2, activity2))
|
|
330
|
+
]
|
|
331
|
+
queue_requests(requests)
|
|
332
|
+
|
|
333
|
+
stats_manager = TransferStatsManager()
|
|
334
|
+
stats_manager.observe(
|
|
335
|
+
src_rse_id=src_rse_id,
|
|
336
|
+
dst_rse_id=dst_rse_id,
|
|
337
|
+
activity=activity1,
|
|
338
|
+
state=RequestState.DONE,
|
|
339
|
+
file_size=367,
|
|
340
|
+
)
|
|
341
|
+
stats_manager.observe(
|
|
342
|
+
src_rse_id=src_rse_id,
|
|
343
|
+
dst_rse_id=dst_rse_id,
|
|
344
|
+
activity=activity2,
|
|
345
|
+
state=RequestState.FAILED,
|
|
346
|
+
file_size=1020,
|
|
347
|
+
)
|
|
348
|
+
stats_manager.force_save()
|
|
349
|
+
stats_manager.downsample_and_cleanup()
|
|
350
|
+
|
|
351
|
+
api_endpoint = '/requests/metrics'
|
|
352
|
+
params = {'dst_rse': dst_rse, 'src_rse': src_rse}
|
|
353
|
+
headers_dict = {'X-Rucio-Type': 'user', 'X-Rucio-Account': root_account.external}
|
|
354
|
+
response = rest_client.get(api_endpoint, query_string=params, headers=headers(auth(auth_token), vohdr(vo), hdrdict(headers_dict)))
|
|
355
|
+
metric = json.loads(response.get_data(as_text=True))
|
|
356
|
+
assert metric['distance'] == 10
|
|
357
|
+
assert metric['bytes']['queued'][activity1] == replica_bytes
|
|
358
|
+
assert metric['bytes']['queued'][activity2] == replica_bytes
|
|
359
|
+
assert metric['bytes']['queued-total'] == 2 * replica_bytes
|
|
360
|
+
assert metric['files']['queued'][activity1] == 1
|
|
361
|
+
assert metric['files']['queued'][activity2] == 1
|
|
362
|
+
assert metric['files']['queued-total'] == 2
|
|
363
|
+
assert metric['files']['done'][activity1]['1h'] == 1
|
|
364
|
+
assert metric['bytes']['done'][activity1]['1h'] == 367
|
|
365
|
+
assert metric['files']['failed'][activity2]['1h'] == 1
|
|
366
|
+
assert metric['src_rse'] == src_rse
|
|
367
|
+
assert metric['dst_rse'] == dst_rse
|
|
368
|
+
|
|
369
|
+
params = {'dst_rse': dst_rse, 'src_rse': src_rse, 'format': 'panda'}
|
|
370
|
+
response = rest_client.get(api_endpoint, query_string=params, headers=headers(auth(auth_token), vohdr(vo), hdrdict(headers_dict)))
|
|
371
|
+
response = json.loads(response.get_data(as_text=True))
|
|
372
|
+
metric = response.get(f'{src_rse}:{dst_rse}')
|
|
373
|
+
assert metric is not None
|
|
@@ -148,7 +148,7 @@ def test_get_hops(rse_factory):
|
|
|
148
148
|
assert hop4['dest_rse'].id == rse6_id
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
def test_disk_vs_tape_priority(rse_factory, root_account, mock_scope):
|
|
151
|
+
def test_disk_vs_tape_priority(rse_factory, root_account, mock_scope, file_config_mock):
|
|
152
152
|
tape1_rse_name, tape1_rse_id = rse_factory.make_posix_rse(rse_type=RSEType.TAPE)
|
|
153
153
|
tape2_rse_name, tape2_rse_id = rse_factory.make_posix_rse(rse_type=RSEType.TAPE)
|
|
154
154
|
disk1_rse_name, disk1_rse_id = rse_factory.make_posix_rse(rse_type=RSEType.DISK)
|
|
@@ -215,6 +215,38 @@ def test_disk_vs_tape_priority(rse_factory, root_account, mock_scope):
|
|
|
215
215
|
assert transfer[0].legacy_sources[0][0] == tape1_rse_name
|
|
216
216
|
|
|
217
217
|
|
|
218
|
+
@pytest.mark.parametrize("file_config_mock", [
|
|
219
|
+
{"overrides": [('transfers', 'source_ranking_strategies', 'PathDistance')]},
|
|
220
|
+
{"overrides": [('transfers', 'source_ranking_strategies', 'PreferDiskOverTape,PathDistance')]}
|
|
221
|
+
], indirect=True)
|
|
222
|
+
def test_disk_vs_tape_with_custom_strategy(rse_factory, root_account, mock_scope, file_config_mock):
|
|
223
|
+
"""
|
|
224
|
+
Disk RSEs are preferred over tape only if the PreferDiskOverTape strategy is set.
|
|
225
|
+
"""
|
|
226
|
+
disk_rse_name, disk_rse_id = rse_factory.make_posix_rse(rse_type=RSEType.DISK)
|
|
227
|
+
tape_rse_name, tape_rse_id = rse_factory.make_posix_rse(rse_type=RSEType.TAPE)
|
|
228
|
+
dst_rse_name, dst_rse_id = rse_factory.make_posix_rse()
|
|
229
|
+
all_rses = [tape_rse_id, disk_rse_id, dst_rse_id]
|
|
230
|
+
add_distance(disk_rse_id, dst_rse_id, distance=20)
|
|
231
|
+
add_distance(tape_rse_id, dst_rse_id, distance=10)
|
|
232
|
+
|
|
233
|
+
file = {'scope': mock_scope, 'name': 'lfn.' + generate_uuid(), 'type': 'FILE', 'bytes': 1, 'adler32': 'beefdead'}
|
|
234
|
+
did = {'scope': file['scope'], 'name': file['name']}
|
|
235
|
+
for rse_id in [tape_rse_id, disk_rse_id]:
|
|
236
|
+
add_replicas(rse_id=rse_id, files=[file], account=root_account)
|
|
237
|
+
|
|
238
|
+
rule_core.add_rule(dids=[did], account=root_account, copies=1, rse_expression=dst_rse_name, grouping='ALL', weight=None, lifetime=None, locked=False, subscription_id=None)
|
|
239
|
+
topology = Topology().configure_multihop()
|
|
240
|
+
requests = list_and_mark_transfer_requests_and_source_replicas(rse_collection=topology, rses=all_rses)
|
|
241
|
+
|
|
242
|
+
[[_, [transfer]]] = pick_and_prepare_submission_path(topology=topology, protocol_factory=ProtocolFactory(),
|
|
243
|
+
requests_with_sources=requests).items()
|
|
244
|
+
if 'PreferDiskOverTape' in file_config_mock.get('transfers', 'source_ranking_strategies'):
|
|
245
|
+
assert transfer[0].src.rse.name == disk_rse_name
|
|
246
|
+
else:
|
|
247
|
+
assert transfer[0].src.rse.name == tape_rse_name
|
|
248
|
+
|
|
249
|
+
|
|
218
250
|
@pytest.mark.parametrize("caches_mock", [{"caches_to_mock": [
|
|
219
251
|
'rucio.core.rse_expression_parser.REGION', # The list of multihop RSEs is retrieved by an expression
|
|
220
252
|
]}], indirect=True)
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
import pytest
|
|
17
|
-
|
|
18
|
-
from rucio.client.didclient import DIDClient
|
|
19
|
-
from rucio.common.config import config_get_bool
|
|
20
|
-
from rucio.common.types import InternalAccount, InternalScope
|
|
21
|
-
from rucio.common.utils import generate_uuid
|
|
22
|
-
from rucio.core.rse import get_rse_id
|
|
23
|
-
from rucio.core.temporary_did import (add_temporary_dids, compose, delete_temporary_dids,
|
|
24
|
-
list_expired_temporary_dids)
|
|
25
|
-
from rucio.tests.common_server import get_vo
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@pytest.mark.noparallel(reason='uses pre-defined RSE')
|
|
29
|
-
def test_core_temporary_dids():
|
|
30
|
-
""" TMP DATA IDENTIFIERS (CORE): """
|
|
31
|
-
|
|
32
|
-
if config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
|
|
33
|
-
vo = {'vo': get_vo()}
|
|
34
|
-
else:
|
|
35
|
-
vo = {}
|
|
36
|
-
scope = InternalScope('mock', **vo)
|
|
37
|
-
root = InternalAccount('root', **vo)
|
|
38
|
-
temporary_dids = []
|
|
39
|
-
rse = 'MOCK'
|
|
40
|
-
rse_id = get_rse_id(rse=rse, **vo)
|
|
41
|
-
for _ in range(10):
|
|
42
|
-
temporary_dids.append({'scope': scope,
|
|
43
|
-
'name': 'object_%s' % generate_uuid(),
|
|
44
|
-
'rse_id': rse_id,
|
|
45
|
-
'bytes': 1,
|
|
46
|
-
'path': None})
|
|
47
|
-
|
|
48
|
-
add_temporary_dids(dids=temporary_dids, account=root)
|
|
49
|
-
|
|
50
|
-
compose(scope=scope, name='file_%s' % generate_uuid(), rse_id=rse_id,
|
|
51
|
-
bytes_=10, sources=temporary_dids, account=root,
|
|
52
|
-
md5=None, adler32=None, pfn=None, meta={}, rules=[],
|
|
53
|
-
parent_scope=None, parent_name=None)
|
|
54
|
-
|
|
55
|
-
dids = list_expired_temporary_dids(rse_id=rse_id, limit=10)
|
|
56
|
-
|
|
57
|
-
rowcount = delete_temporary_dids(dids=dids)
|
|
58
|
-
|
|
59
|
-
assert rowcount == 10
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@pytest.mark.noparallel(reason='uses pre-defined RSE')
|
|
63
|
-
def test_client_temporary_dids():
|
|
64
|
-
""" TMP DATA IDENTIFIERS (CLIENT): """
|
|
65
|
-
client = DIDClient()
|
|
66
|
-
temporary_dids = []
|
|
67
|
-
for _ in range(10):
|
|
68
|
-
temporary_dids.append({'scope': 'mock',
|
|
69
|
-
'name': 'object_%s' % generate_uuid(),
|
|
70
|
-
'rse': 'MOCK',
|
|
71
|
-
'bytes': 1,
|
|
72
|
-
'path': None})
|
|
73
|
-
|
|
74
|
-
client.add_temporary_dids(dids=temporary_dids)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|