mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 12:28:52 +00:00
* test: add benc2cpp.py, a benc beautifier for hardcoded cpp test cases * test: add .resume file unit test * refactor: use api_compat::convert_incoming_data() and convert_outgoing_data() on .resume files * chore: mark TR_KEY_peers2_6_kebab as APICOMPAT * chore: mark TR_KEY_speed_Bps_kebab as APICOMPAT * chore: mark TR_KEY_use_speed_limit_kebab as APICOMPAT * chore: mark as APICOMPAT: TR_KEY_use_global_speed_limit_kebab * chore: mark as APICOMPAT: TR_KEY_ratio_mode_kebab * chore: mark as APICOMPAT: TR_KEY_idle_limit_kebab * chore: mark as APICOMPAT: TR_KEY_idle_mode_kebab * chore: mark as APICOMPAT: TR_KEY_max_peers_kebab * chore: mark as APICOMPAT: TR_KEY_added_date_kebab * chore: mark as APICOMPAT: TR_KEY_seeding_time_seconds_kebab * chore: mark as APICOMPAT: TR_KEY_downloading_time_seconds_kebab * chore: mark as APICOMPAT: TR_KEY_bandwidth_priority * chore: mark as APICOMPAT: TR_KEY_done_date_kebab * chore: mark as APICOMPAT: TR_KEY_activity_date_kebab * chore: remove remaining _kebab cases from resume.cc * chore: clang-format
1063 lines
35 KiB
C++
1063 lines
35 KiB
C++
// This file Copyright © Mnemosyne LLC.
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
// License text can be found in the licenses/ folder.
|
|
|
|
#include <string_view>
|
|
|
|
#include <libtransmission/api-compat.h>
|
|
#include <libtransmission/quark.h>
|
|
#include <libtransmission/variant.h>
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "test-fixtures.h"
|
|
|
|
namespace
|
|
{
|
|
|
|
constexpr std::string_view LegacySessionGetJson = R"json({
|
|
"method": "session-get",
|
|
"tag": 0
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentSessionGetJson = R"json({
|
|
"id": 0,
|
|
"jsonrpc": "2.0",
|
|
"method": "session_get"
|
|
})json";
|
|
|
|
constexpr std::string_view LegacySessionGetResponseJson = R"json({
|
|
"arguments": {
|
|
"alt-speed-down": 50,
|
|
"alt-speed-enabled": false,
|
|
"alt-speed-time-begin": 540,
|
|
"alt-speed-time-day": 127,
|
|
"alt-speed-time-enabled": false,
|
|
"alt-speed-time-end": 1020,
|
|
"alt-speed-up": 50,
|
|
"anti-brute-force-enabled": false,
|
|
"anti-brute-force-threshold": 100,
|
|
"blocklist-enabled": false,
|
|
"blocklist-size": 0,
|
|
"blocklist-url": "http://www.example.com/blocklist",
|
|
"cache-size-mb": 4,
|
|
"config-dir": "/home/user/.config/transmission",
|
|
"default-trackers": "",
|
|
"dht-enabled": true,
|
|
"download-dir": "/home/user/Downloads",
|
|
"download-dir-free-space": 2199023255552,
|
|
"download-queue-enabled": true,
|
|
"download-queue-size": 4,
|
|
"encryption": "preferred",
|
|
"idle-seeding-limit": 30,
|
|
"idle-seeding-limit-enabled": false,
|
|
"incomplete-dir": "/home/user/Downloads",
|
|
"incomplete-dir-enabled": false,
|
|
"lpd-enabled": false,
|
|
"peer-limit-global": 200,
|
|
"peer-limit-per-torrent": 50,
|
|
"peer-port": 51413,
|
|
"peer-port-random-on-start": false,
|
|
"pex-enabled": true,
|
|
"port-forwarding-enabled": true,
|
|
"preferred_transports": [
|
|
"utp",
|
|
"tcp"
|
|
],
|
|
"queue-stalled-enabled": true,
|
|
"queue-stalled-minutes": 30,
|
|
"rename-partial-files": true,
|
|
"reqq": 2000,
|
|
"rpc-version": 18,
|
|
"rpc-version-minimum": 14,
|
|
"rpc-version-semver": "6.0.0",
|
|
"script-torrent-added-enabled": false,
|
|
"script-torrent-added-filename": "",
|
|
"script-torrent-done-enabled": false,
|
|
"script-torrent-done-filename": "/home/user/scripts/script.sh",
|
|
"script-torrent-done-seeding-enabled": false,
|
|
"script-torrent-done-seeding-filename": "",
|
|
"seed-queue-enabled": false,
|
|
"seed-queue-size": 10,
|
|
"seedRatioLimit": 2.0,
|
|
"seedRatioLimited": false,
|
|
"sequential_download": false,
|
|
"session-id": "pdvuklydohaohwwluzpmpmllkaopzzlzzpvupkpuavhjhlzhyjfwoly",
|
|
"speed-limit-down": 100.0,
|
|
"speed-limit-down-enabled": false,
|
|
"speed-limit-up": 100.0,
|
|
"speed-limit-up-enabled": false,
|
|
"start-added-torrents": true,
|
|
"tcp-enabled": true,
|
|
"trash-original-torrent-files": false,
|
|
"units": {
|
|
"memory-bytes": 1024,
|
|
"memory-units": [
|
|
"B",
|
|
"KiB",
|
|
"MiB",
|
|
"GiB",
|
|
"TiB"
|
|
],
|
|
"size-bytes": 1000,
|
|
"size-units": [
|
|
"B",
|
|
"kB",
|
|
"MB",
|
|
"GB",
|
|
"TB"
|
|
],
|
|
"speed-bytes": 1000,
|
|
"speed-units": [
|
|
"B/s",
|
|
"kB/s",
|
|
"MB/s",
|
|
"GB/s",
|
|
"TB/s"
|
|
]
|
|
},
|
|
"utp-enabled": true,
|
|
"version": "4.1.0-beta.4 (b11bfd9712)"
|
|
},
|
|
"result": "success",
|
|
"tag": 40
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentSessionGetResponseJson = R"json({
|
|
"id": 40,
|
|
"jsonrpc": "2.0",
|
|
"result": {
|
|
"alt_speed_down": 50,
|
|
"alt_speed_enabled": false,
|
|
"alt_speed_time_begin": 540,
|
|
"alt_speed_time_day": 127,
|
|
"alt_speed_time_enabled": false,
|
|
"alt_speed_time_end": 1020,
|
|
"alt_speed_up": 50,
|
|
"anti_brute_force_enabled": false,
|
|
"anti_brute_force_threshold": 100,
|
|
"blocklist_enabled": false,
|
|
"blocklist_size": 0,
|
|
"blocklist_url": "http://www.example.com/blocklist",
|
|
"cache_size_mb": 4,
|
|
"config_dir": "/home/user/.config/transmission",
|
|
"default_trackers": "",
|
|
"dht_enabled": true,
|
|
"download_dir": "/home/user/Downloads",
|
|
"download_dir_free_space": 2199023255552,
|
|
"download_queue_enabled": true,
|
|
"download_queue_size": 4,
|
|
"encryption": "preferred",
|
|
"idle_seeding_limit": 30,
|
|
"idle_seeding_limit_enabled": false,
|
|
"incomplete_dir": "/home/user/Downloads",
|
|
"incomplete_dir_enabled": false,
|
|
"lpd_enabled": false,
|
|
"peer_limit_global": 200,
|
|
"peer_limit_per_torrent": 50,
|
|
"peer_port": 51413,
|
|
"peer_port_random_on_start": false,
|
|
"pex_enabled": true,
|
|
"port_forwarding_enabled": true,
|
|
"preferred_transports": [
|
|
"utp",
|
|
"tcp"
|
|
],
|
|
"queue_stalled_enabled": true,
|
|
"queue_stalled_minutes": 30,
|
|
"rename_partial_files": true,
|
|
"reqq": 2000,
|
|
"rpc_version": 18,
|
|
"rpc_version_minimum": 14,
|
|
"rpc_version_semver": "6.0.0",
|
|
"script_torrent_added_enabled": false,
|
|
"script_torrent_added_filename": "",
|
|
"script_torrent_done_enabled": false,
|
|
"script_torrent_done_filename": "/home/user/scripts/script.sh",
|
|
"script_torrent_done_seeding_enabled": false,
|
|
"script_torrent_done_seeding_filename": "",
|
|
"seed_queue_enabled": false,
|
|
"seed_queue_size": 10,
|
|
"seed_ratio_limit": 2.0,
|
|
"seed_ratio_limited": false,
|
|
"sequential_download": false,
|
|
"session_id": "pdvuklydohaohwwluzpmpmllkaopzzlzzpvupkpuavhjhlzhyjfwoly",
|
|
"speed_limit_down": 100.0,
|
|
"speed_limit_down_enabled": false,
|
|
"speed_limit_up": 100.0,
|
|
"speed_limit_up_enabled": false,
|
|
"start_added_torrents": true,
|
|
"tcp_enabled": true,
|
|
"trash_original_torrent_files": false,
|
|
"units": {
|
|
"memory_bytes": 1024,
|
|
"memory_units": [
|
|
"B",
|
|
"KiB",
|
|
"MiB",
|
|
"GiB",
|
|
"TiB"
|
|
],
|
|
"size_bytes": 1000,
|
|
"size_units": [
|
|
"B",
|
|
"kB",
|
|
"MB",
|
|
"GB",
|
|
"TB"
|
|
],
|
|
"speed_bytes": 1000,
|
|
"speed_units": [
|
|
"B/s",
|
|
"kB/s",
|
|
"MB/s",
|
|
"GB/s",
|
|
"TB/s"
|
|
]
|
|
},
|
|
"utp_enabled": true,
|
|
"version": "4.1.0-beta.4 (b11bfd9712)"
|
|
}
|
|
})json";
|
|
|
|
constexpr std::string_view LegacyTorrentGetJson = R"json({
|
|
"arguments": {
|
|
"fields": [
|
|
"downloadDir",
|
|
"downloadedEver",
|
|
"editDate",
|
|
"error",
|
|
"errorString",
|
|
"eta",
|
|
"haveUnchecked",
|
|
"haveValid",
|
|
"id",
|
|
"isFinished",
|
|
"leftUntilDone",
|
|
"manualAnnounceTime",
|
|
"metadataPercentComplete",
|
|
"name",
|
|
"peersConnected",
|
|
"peersGettingFromUs",
|
|
"peersSendingToUs",
|
|
"percentDone",
|
|
"queuePosition",
|
|
"rateDownload",
|
|
"rateUpload",
|
|
"recheckProgress",
|
|
"seedRatioLimit",
|
|
"seedRatioMode",
|
|
"sizeWhenDone",
|
|
"status",
|
|
"uploadRatio",
|
|
"uploadedEver",
|
|
"webseedsSendingToUs"
|
|
],
|
|
"ids": "recently-active"
|
|
},
|
|
"method": "torrent-get",
|
|
"tag": 6
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentTorrentGetJson = R"json({
|
|
"id": 6,
|
|
"jsonrpc": "2.0",
|
|
"method": "torrent_get",
|
|
"params": {
|
|
"fields": [
|
|
"download_dir",
|
|
"downloaded_ever",
|
|
"edit_date",
|
|
"error",
|
|
"error_string",
|
|
"eta",
|
|
"have_unchecked",
|
|
"have_valid",
|
|
"id",
|
|
"is_finished",
|
|
"left_until_done",
|
|
"manual_announce_time",
|
|
"metadata_percent_complete",
|
|
"name",
|
|
"peers_connected",
|
|
"peers_getting_from_us",
|
|
"peers_sending_to_us",
|
|
"percent_done",
|
|
"queue_position",
|
|
"rate_download",
|
|
"rate_upload",
|
|
"recheck_progress",
|
|
"seed_ratio_limit",
|
|
"seed_ratio_mode",
|
|
"size_when_done",
|
|
"status",
|
|
"upload_ratio",
|
|
"uploaded_ever",
|
|
"webseeds_sending_to_us"
|
|
],
|
|
"ids": "recently_active"
|
|
}
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentPortTestErrorResponse = R"json({
|
|
"error": {
|
|
"code": 8,
|
|
"data": {
|
|
"error_string": "Couldn't test port: No Response (0)",
|
|
"result": {
|
|
"ip_protocol": "ipv6"
|
|
}
|
|
},
|
|
"message": "HTTP error from backend service"
|
|
},
|
|
"id": 9,
|
|
"jsonrpc": "2.0"
|
|
})json";
|
|
|
|
constexpr std::string_view LegacyPortTestErrorResponse = R"json({
|
|
"arguments": {
|
|
"ip_protocol": "ipv6"
|
|
},
|
|
"result": "Couldn't test port: No Response (0)",
|
|
"tag": 9
|
|
})json";
|
|
|
|
constexpr std::string_view LegacyStatsJson = R"json({
|
|
"downloaded-bytes": 12,
|
|
"files-added": 34,
|
|
"seconds-active": 56,
|
|
"session-count": 78,
|
|
"uploaded-bytes": 90
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentStatsJson = R"json({
|
|
"downloaded_bytes": 12,
|
|
"files_added": 34,
|
|
"seconds_active": 56,
|
|
"session_count": 78,
|
|
"uploaded_bytes": 90
|
|
})json";
|
|
|
|
constexpr std::string_view LegacySettingsJson = R"json({
|
|
"alt-speed-down": 50,
|
|
"alt-speed-enabled": false,
|
|
"alt-speed-time-begin": 540,
|
|
"alt-speed-time-day": 127,
|
|
"alt-speed-time-enabled": false,
|
|
"alt-speed-time-end": 1020,
|
|
"alt-speed-up": 50,
|
|
"blocklist-date": 0,
|
|
"blocklist-enabled": false,
|
|
"blocklist-updates-enabled": true,
|
|
"blocklist-url": "http://www.example.com/blocklist",
|
|
"compact-view": false,
|
|
"default-trackers": "",
|
|
"dht-enabled": true,
|
|
"download-dir": "/home/user/Downloads",
|
|
"download-queue-enabled": true,
|
|
"download-queue-size": 5,
|
|
"encryption": 1,
|
|
"filter-mode": "show-all",
|
|
"filter-trackers": "",
|
|
"idle-seeding-limit": 30,
|
|
"idle-seeding-limit-enabled": false,
|
|
"incomplete-dir": "/home/user/Downloads",
|
|
"incomplete-dir-enabled": false,
|
|
"inhibit-desktop-hibernation": false,
|
|
"lpd-enabled": true,
|
|
"main-window-height": 500,
|
|
"main-window-layout-order": "menu,toolbar,filter,list,statusbar",
|
|
"main-window-width": 650,
|
|
"main-window-x": 3840,
|
|
"main-window-y": 0,
|
|
"message-level": 4,
|
|
"open-dialog-dir": "/home/user",
|
|
"peer-limit-global": 200,
|
|
"peer-limit-per-torrent": 50,
|
|
"peer-port": 51413,
|
|
"peer-port-random-high": 65535,
|
|
"peer-port-random-low": 49152,
|
|
"peer-port-random-on-start": false,
|
|
"peer-socket-tos": "le",
|
|
"pex-enabled": true,
|
|
"port-forwarding-enabled": true,
|
|
"preallocation": 1,
|
|
"prompt-before-exit": true,
|
|
"queue-stalled-minutes": 30,
|
|
"ratio-limit": 2.0,
|
|
"ratio-limit-enabled": false,
|
|
"read-clipboard": false,
|
|
"remote-session-enabled": false,
|
|
"remote-session-host": "localhost",
|
|
"remote-session-https": false,
|
|
"remote-session-password": "",
|
|
"remote-session-port": 9091,
|
|
"remote-session-requres-authentication": false,
|
|
"remote-session-username": "",
|
|
"rename-partial-files": true,
|
|
"rpc-authentication-required": false,
|
|
"rpc-enabled": false,
|
|
"rpc-password": "",
|
|
"rpc-port": 9091,
|
|
"rpc-username": "",
|
|
"rpc-whitelist": "127.0.0.1,::1",
|
|
"rpc-whitelist-enabled": true,
|
|
"script-torrent-done-enabled": false,
|
|
"script-torrent-done-filename": "",
|
|
"script-torrent-done-seeding-enabled": false,
|
|
"script-torrent-done-seeding-filename": "",
|
|
"show-backup-trackers": false,
|
|
"show-filterbar": true,
|
|
"show-notification-area-icon": false,
|
|
"show-options-window": true,
|
|
"show-statusbar": true,
|
|
"show-toolbar": true,
|
|
"show-tracker-scrapes": false,
|
|
"sleep-per-seconds-during-verify": 100,
|
|
"sort-mode": "sort-by-name",
|
|
"sort-reversed": false,
|
|
"speed-limit-down": 100,
|
|
"speed-limit-down-enabled": false,
|
|
"speed-limit-up": 100,
|
|
"speed-limit-up-enabled": false,
|
|
"start-added-torrents": true,
|
|
"start-minimized": false,
|
|
"statusbar-stats": "total-ratio",
|
|
"torrent-added-notification-enabled": true,
|
|
"torrent-complete-notification-enabled": true,
|
|
"torrent-complete-sound-command": [
|
|
"canberra-gtk-play",
|
|
"-i",
|
|
"complete-download",
|
|
"-d",
|
|
"transmission torrent downloaded"
|
|
],
|
|
"torrent-complete-sound-enabled": true,
|
|
"trash-original-torrent-files": false,
|
|
"upload-slots-per-torrent": 8,
|
|
"utp-enabled": true,
|
|
"watch-dir": "/home/user/Downloads",
|
|
"watch-dir-enabled": false
|
|
})json";
|
|
|
|
constexpr std::string_view CurrentSettingsJson = R"json({
|
|
"alt_speed_down": 50,
|
|
"alt_speed_enabled": false,
|
|
"alt_speed_time_begin": 540,
|
|
"alt_speed_time_day": 127,
|
|
"alt_speed_time_enabled": false,
|
|
"alt_speed_time_end": 1020,
|
|
"alt_speed_up": 50,
|
|
"blocklist_date": 0,
|
|
"blocklist_enabled": false,
|
|
"blocklist_updates_enabled": true,
|
|
"blocklist_url": "http://www.example.com/blocklist",
|
|
"compact_view": false,
|
|
"default_trackers": "",
|
|
"dht_enabled": true,
|
|
"download_dir": "/home/user/Downloads",
|
|
"download_queue_enabled": true,
|
|
"download_queue_size": 5,
|
|
"encryption": 1,
|
|
"filter_mode": "show-all",
|
|
"filter_trackers": "",
|
|
"idle_seeding_limit": 30,
|
|
"idle_seeding_limit_enabled": false,
|
|
"incomplete_dir": "/home/user/Downloads",
|
|
"incomplete_dir_enabled": false,
|
|
"inhibit_desktop_hibernation": false,
|
|
"lpd_enabled": true,
|
|
"main_window_height": 500,
|
|
"main_window_layout_order": "menu,toolbar,filter,list,statusbar",
|
|
"main_window_width": 650,
|
|
"main_window_x": 3840,
|
|
"main_window_y": 0,
|
|
"message_level": 4,
|
|
"open_dialog_dir": "/home/user",
|
|
"peer_limit_global": 200,
|
|
"peer_limit_per_torrent": 50,
|
|
"peer_port": 51413,
|
|
"peer_port_random_high": 65535,
|
|
"peer_port_random_low": 49152,
|
|
"peer_port_random_on_start": false,
|
|
"peer_socket_tos": "le",
|
|
"pex_enabled": true,
|
|
"port_forwarding_enabled": true,
|
|
"preallocation": 1,
|
|
"prompt_before_exit": true,
|
|
"queue_stalled_minutes": 30,
|
|
"ratio_limit": 2.0,
|
|
"ratio_limit_enabled": false,
|
|
"read_clipboard": false,
|
|
"remote_session_enabled": false,
|
|
"remote_session_host": "localhost",
|
|
"remote_session_https": false,
|
|
"remote_session_password": "",
|
|
"remote_session_port": 9091,
|
|
"remote_session_requires_authentication": false,
|
|
"remote_session_username": "",
|
|
"rename_partial_files": true,
|
|
"rpc_authentication_required": false,
|
|
"rpc_enabled": false,
|
|
"rpc_password": "",
|
|
"rpc_port": 9091,
|
|
"rpc_username": "",
|
|
"rpc_whitelist": "127.0.0.1,::1",
|
|
"rpc_whitelist_enabled": true,
|
|
"script_torrent_done_enabled": false,
|
|
"script_torrent_done_filename": "",
|
|
"script_torrent_done_seeding_enabled": false,
|
|
"script_torrent_done_seeding_filename": "",
|
|
"show_backup_trackers": false,
|
|
"show_filterbar": true,
|
|
"show_notification_area_icon": false,
|
|
"show_options_window": true,
|
|
"show_statusbar": true,
|
|
"show_toolbar": true,
|
|
"show_tracker_scrapes": false,
|
|
"sleep_per_seconds_during_verify": 100,
|
|
"sort_mode": "sort-by-name",
|
|
"sort_reversed": false,
|
|
"speed_limit_down": 100,
|
|
"speed_limit_down_enabled": false,
|
|
"speed_limit_up": 100,
|
|
"speed_limit_up_enabled": false,
|
|
"start_added_torrents": true,
|
|
"start_minimized": false,
|
|
"statusbar_stats": "total-ratio",
|
|
"torrent_added_notification_enabled": true,
|
|
"torrent_complete_notification_enabled": true,
|
|
"torrent_complete_sound_command": [
|
|
"canberra-gtk-play",
|
|
"-i",
|
|
"complete-download",
|
|
"-d",
|
|
"transmission torrent downloaded"
|
|
],
|
|
"torrent_complete_sound_enabled": true,
|
|
"trash_original_torrent_files": false,
|
|
"upload_slots_per_torrent": 8,
|
|
"utp_enabled": true,
|
|
"watch_dir": "/home/user/Downloads",
|
|
"watch_dir_enabled": false
|
|
})json";
|
|
|
|
constexpr std::string_view BadFreeSpaceRequest = R"json({
|
|
"id": 39693,
|
|
"jsonrpc": "2.0",
|
|
"method": "free_space",
|
|
"params": {
|
|
"path": "this/path/is/not/absolute"
|
|
}
|
|
})json";
|
|
|
|
constexpr std::string_view BadFreeSpaceRequestLegacy = R"json({
|
|
"arguments": {
|
|
"path": "this/path/is/not/absolute"
|
|
},
|
|
"method": "free-space",
|
|
"tag": 39693
|
|
})json";
|
|
|
|
constexpr std::string_view BadFreeSpaceResponse = R"json({
|
|
"error": {
|
|
"code": 3,
|
|
"data": {
|
|
"error_string": "directory path is not absolute"
|
|
},
|
|
"message": "path is not absolute"
|
|
},
|
|
"id": 39693,
|
|
"jsonrpc": "2.0"
|
|
})json";
|
|
|
|
constexpr std::string_view BadFreeSpaceResponseLegacy = R"json({
|
|
"arguments": {},
|
|
"result": "directory path is not absolute",
|
|
"tag": 39693
|
|
})json";
|
|
|
|
constexpr std::string_view WellFormedFreeSpaceRequest = R"json({
|
|
"id": 41414,
|
|
"jsonrpc": "2.0",
|
|
"method": "free_space",
|
|
"params": {
|
|
"path": "/this/path/does/not/exist"
|
|
}
|
|
})json";
|
|
|
|
constexpr std::string_view WellFormedFreeSpaceResponse = R"json({
|
|
"id": 41414,
|
|
"jsonrpc": "2.0",
|
|
"result": {
|
|
"path": "/this/path/does/not/exist",
|
|
"size_bytes": -1,
|
|
"total_size": -1
|
|
}
|
|
})json";
|
|
|
|
constexpr std::string_view WellFormedFreeSpaceLegacyRequest = R"json({
|
|
"arguments": {
|
|
"path": "/this/path/does/not/exist"
|
|
},
|
|
"method": "free-space",
|
|
"tag": 41414
|
|
})json";
|
|
|
|
constexpr std::string_view WellFormedFreeSpaceLegacyResponse = R"json({
|
|
"arguments": {
|
|
"path": "/this/path/does/not/exist",
|
|
"size-bytes": -1,
|
|
"total_size": -1
|
|
},
|
|
"result": "success",
|
|
"tag": 41414
|
|
})json";
|
|
|
|
constexpr std::string_view BadMethodNameResponse = R"json({
|
|
"error": {
|
|
"code": -32601,
|
|
"message": "Method not found"
|
|
},
|
|
"id": 39693,
|
|
"jsonrpc": "2.0"
|
|
})json";
|
|
|
|
constexpr std::string_view BadMethodNameLegacyResponse = R"json({
|
|
"arguments": {},
|
|
"result": "no method name",
|
|
"tag": 39693
|
|
})json";
|
|
|
|
constexpr std::string_view UnrecognisedInfoResponse = R"json({
|
|
"error": {
|
|
"code": 4,
|
|
"message": "unrecognized info"
|
|
},
|
|
"id": 10,
|
|
"jsonrpc": "2.0"
|
|
})json";
|
|
|
|
constexpr std::string_view UnrecognisedInfoLegacyResponse = R"json({
|
|
"arguments": {},
|
|
"result": "unrecognized info",
|
|
"tag": 10
|
|
})json";
|
|
|
|
// clang-format off
|
|
constexpr std::string_view LegacyResumeBenc =
|
|
"d"
|
|
"13:activity-date" "i1765724117e"
|
|
"10:added-date" "i1756689559e"
|
|
"18:bandwidth-priority" "i0e"
|
|
"7:corrupt" "i0e"
|
|
"11:destination" "30:/data/trackers/untracked/Books"
|
|
"3:dnd"
|
|
"l"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"e"
|
|
"9:done-date" "i1756689845e"
|
|
"10:downloaded" "i4830420542e"
|
|
"24:downloading-time-seconds" "i286e"
|
|
"5:files"
|
|
"l"
|
|
"102:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v01 - Oz - Baum - The Wonderful Wizard of Oz (1990).epub"
|
|
"100:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v02 - Oz - Baum - The Marvelous Land of Oz (1904).epub"
|
|
"86:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v03 - Oz - Baum - Ozma of Oz (1907).epub"
|
|
"104:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v04 - Oz - Baum - Dorothy and the Wizard in Oz (1908).epub"
|
|
"90:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v05 - Oz - Baum - The Road to Oz (1909).epub"
|
|
"98:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v06 - Oz - Baum - The Emerald City of Oz (1910).epub"
|
|
"100:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v07 - Oz - Baum - The Patchwork Girl of Oz (1913).epub"
|
|
"e"
|
|
"5:group" "0:"
|
|
"10:idle-limit"
|
|
"d"
|
|
"10:idle-limit" "i30e"
|
|
"9:idle-mode" "i0e"
|
|
"e"
|
|
"6:labels"
|
|
"l"
|
|
"e"
|
|
"9:max-peers" "i20e"
|
|
"4:name" "45:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7"
|
|
"6:paused" "i0e"
|
|
"6:peers2"
|
|
"l"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x80\x3b\xac\x8f\x3b\x1c"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xe2\xa1\xe3\x25\x2c\xfa"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xf2\x50\x82\xab\xed\x08"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xeb\xb2\x8c\xa1\x1e\xc6"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xe8\x92\x9e\x87\xd1\xb4"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x0a\xca\x51\xdd\x61\x52"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x3d\xf0\x9c\x23\x55\x20"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x4d\x9f\x2e\xd9\x40\x9e"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i12e"
|
|
"14:socket_address" "6:\x83\xa6\xd7\x7f\xa3\x4c"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xcd\x4a\xdf\x95\xc8\xaa"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x78\x5b\x6c\x9b\xa8\x38"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x60\xc6\xe0\x11\xc5\x76"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xd4\xfa\x37\x77\x0f\xe4"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xfb\x28\x6c\x4d\xc3\x02"
|
|
"e"
|
|
"e"
|
|
"8:priority"
|
|
"l"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"e"
|
|
"8:progress"
|
|
"d"
|
|
"6:blocks" "3:all"
|
|
"6:mtimes"
|
|
"l"
|
|
"i1756689844e"
|
|
"i1756689800e"
|
|
"i1756689836e"
|
|
"i1756689812e"
|
|
"i1756689839e"
|
|
"i1756689844e"
|
|
"i1756689804e"
|
|
"e"
|
|
"6:pieces" "3:all"
|
|
"e"
|
|
"11:ratio-limit"
|
|
"d"
|
|
"11:ratio-limit" "8:2.000000"
|
|
"10:ratio-mode" "i0e"
|
|
"e"
|
|
"20:seeding-time-seconds" "i7373039e"
|
|
"19:sequential_download" "i0e"
|
|
"30:sequential_download_from_piece" "i0e"
|
|
"16:speed-limit-down"
|
|
"d"
|
|
"9:speed-Bps" "i2000000e"
|
|
"22:use-global-speed-limit" "i1e"
|
|
"15:use-speed-limit" "i0e"
|
|
"e"
|
|
"14:speed-limit-up"
|
|
"d"
|
|
"9:speed-Bps" "i5000000e"
|
|
"22:use-global-speed-limit" "i1e"
|
|
"15:use-speed-limit" "i0e"
|
|
"e"
|
|
"8:uploaded" "i98667375637e"
|
|
"e";
|
|
|
|
constexpr std::string_view ResumeBenc =
|
|
"d"
|
|
"13:activity_date" "i1765724117e"
|
|
"10:added_date" "i1756689559e"
|
|
"18:bandwidth_priority" "i0e"
|
|
"7:corrupt" "i0e"
|
|
"11:destination" "30:/data/trackers/untracked/Books"
|
|
"3:dnd"
|
|
"l"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"e"
|
|
"9:done_date" "i1756689845e"
|
|
"10:downloaded" "i4830420542e"
|
|
"24:downloading_time_seconds" "i286e"
|
|
"5:files"
|
|
"l"
|
|
"102:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v01 - Oz - Baum - The Wonderful Wizard of Oz (1990).epub"
|
|
"100:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v02 - Oz - Baum - The Marvelous Land of Oz (1904).epub"
|
|
"86:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v03 - Oz - Baum - Ozma of Oz (1907).epub"
|
|
"104:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v04 - Oz - Baum - Dorothy and the Wizard in Oz (1908).epub"
|
|
"90:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v05 - Oz - Baum - The Road to Oz (1909).epub"
|
|
"98:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v06 - Oz - Baum - The Emerald City of Oz (1910).epub"
|
|
"100:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7/v07 - Oz - Baum - The Patchwork Girl of Oz (1913).epub"
|
|
"e"
|
|
"5:group" "0:"
|
|
"10:idle_limit"
|
|
"d"
|
|
"10:idle_limit" "i30e"
|
|
"9:idle_mode" "i0e"
|
|
"e"
|
|
"6:labels"
|
|
"l"
|
|
"e"
|
|
"9:max_peers" "i20e"
|
|
"4:name" "45:Oz Series - Frank L Baum [PUBLIC DOMAIN] v1-7"
|
|
"6:paused" "i0e"
|
|
"6:peers2"
|
|
"l"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x80\x3b\xac\x8f\x3b\x1c"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xe2\xa1\xe3\x25\x2c\xfa"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xf2\x50\x82\xab\xed\x08"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xeb\xb2\x8c\xa1\x1e\xc6"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xe8\x92\x9e\x87\xd1\xb4"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x0a\xca\x51\xdd\x61\x52"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x3d\xf0\x9c\x23\x55\x20"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x4d\x9f\x2e\xd9\x40\x9e"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i12e"
|
|
"14:socket_address" "6:\x83\xa6\xd7\x7f\xa3\x4c"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xcd\x4a\xdf\x95\xc8\xaa"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x78\x5b\x6c\x9b\xa8\x38"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\x60\xc6\xe0\x11\xc5\x76"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xd4\xfa\x37\x77\x0f\xe4"
|
|
"e"
|
|
"d"
|
|
"5:flags" "i0e"
|
|
"14:socket_address" "6:\xfb\x28\x6c\x4d\xc3\x02"
|
|
"e"
|
|
"e"
|
|
"8:priority"
|
|
"l"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"i0e"
|
|
"e"
|
|
"8:progress"
|
|
"d"
|
|
"6:blocks" "3:all"
|
|
"6:mtimes"
|
|
"l"
|
|
"i1756689844e"
|
|
"i1756689800e"
|
|
"i1756689836e"
|
|
"i1756689812e"
|
|
"i1756689839e"
|
|
"i1756689844e"
|
|
"i1756689804e"
|
|
"e"
|
|
"6:pieces" "3:all"
|
|
"e"
|
|
"11:ratio_limit"
|
|
"d"
|
|
"11:ratio_limit" "8:2.000000"
|
|
"10:ratio_mode" "i0e"
|
|
"e"
|
|
"20:seeding_time_seconds" "i7373039e"
|
|
"19:sequential_download" "i0e"
|
|
"30:sequential_download_from_piece" "i0e"
|
|
"16:speed_limit_down"
|
|
"d"
|
|
"9:speed_Bps" "i2000000e"
|
|
"22:use_global_speed_limit" "i1e"
|
|
"15:use_speed_limit" "i0e"
|
|
"e"
|
|
"14:speed_limit_up"
|
|
"d"
|
|
"9:speed_Bps" "i5000000e"
|
|
"22:use_global_speed_limit" "i1e"
|
|
"15:use_speed_limit" "i0e"
|
|
"e"
|
|
"8:uploaded" "i98667375637e"
|
|
"e";
|
|
// clang-format on
|
|
|
|
} // namespace
|
|
|
|
TEST(ApiCompatTest, canConvertRpc)
|
|
{
|
|
using Style = libtransmission::api_compat::Style;
|
|
using TestCase = std::tuple<std::string_view, std::string_view, Style, std::string_view>;
|
|
|
|
// clang-format off
|
|
static auto constexpr TestCases = std::array<TestCase, 40U>{ {
|
|
{ "free_space tr5 -> tr5", BadFreeSpaceRequest, Style::Tr5, BadFreeSpaceRequest },
|
|
{ "free_space tr5 -> tr4", BadFreeSpaceRequest, Style::Tr4, BadFreeSpaceRequestLegacy },
|
|
{ "free_space tr4 -> tr5", BadFreeSpaceRequestLegacy, Style::Tr5, BadFreeSpaceRequest },
|
|
{ "free_space tr4 -> tr4", BadFreeSpaceRequestLegacy, Style::Tr4, BadFreeSpaceRequestLegacy },
|
|
{ "free_space error response tr5 -> tr5", BadFreeSpaceResponse, Style::Tr5, BadFreeSpaceResponse },
|
|
{ "free_space error response tr5 -> tr4", BadFreeSpaceResponse, Style::Tr4, BadFreeSpaceResponseLegacy },
|
|
{ "free_space error response tr4 -> tr5", BadFreeSpaceResponseLegacy, Style::Tr5, BadFreeSpaceResponse },
|
|
{ "free_space error response tr4 -> tr4", BadFreeSpaceResponseLegacy, Style::Tr4, BadFreeSpaceResponseLegacy },
|
|
{ "free_space req tr5 -> tr5", WellFormedFreeSpaceRequest, Style::Tr5, WellFormedFreeSpaceRequest },
|
|
{ "free_space req tr5 -> tr4", WellFormedFreeSpaceRequest, Style::Tr4, WellFormedFreeSpaceLegacyRequest },
|
|
{ "free_space req tr4 -> tr5", WellFormedFreeSpaceLegacyRequest, Style::Tr5, WellFormedFreeSpaceRequest },
|
|
{ "free_space req tr4 -> tr4", WellFormedFreeSpaceLegacyRequest, Style::Tr4, WellFormedFreeSpaceLegacyRequest },
|
|
{ "free_space response tr5 -> tr5", WellFormedFreeSpaceResponse, Style::Tr5, WellFormedFreeSpaceResponse },
|
|
{ "free_space response tr5 -> tr4", WellFormedFreeSpaceResponse, Style::Tr4, WellFormedFreeSpaceLegacyResponse },
|
|
{ "free_space response tr4 -> tr5", WellFormedFreeSpaceLegacyResponse, Style::Tr5, WellFormedFreeSpaceResponse },
|
|
{ "free_space response tr4 -> tr4", WellFormedFreeSpaceLegacyResponse, Style::Tr4, WellFormedFreeSpaceLegacyResponse },
|
|
{ "session_get tr5 -> tr5", CurrentSessionGetJson, Style::Tr5, CurrentSessionGetJson },
|
|
{ "session_get tr5 -> tr4", CurrentSessionGetJson, Style::Tr4, LegacySessionGetJson },
|
|
{ "session_get tr4 -> tr5", LegacySessionGetJson, Style::Tr5, CurrentSessionGetJson },
|
|
{ "session_get tr4 -> tr4", LegacySessionGetJson, Style::Tr4, LegacySessionGetJson },
|
|
{ "session_get response tr5 -> tr5", CurrentSessionGetResponseJson, Style::Tr5, CurrentSessionGetResponseJson },
|
|
{ "session_get response tr5 -> tr4", CurrentSessionGetResponseJson, Style::Tr4, LegacySessionGetResponseJson },
|
|
{ "session_get response tr4 -> tr5", LegacySessionGetResponseJson, Style::Tr5, CurrentSessionGetResponseJson },
|
|
{ "session_get response tr4 -> tr4", LegacySessionGetResponseJson, Style::Tr4, LegacySessionGetResponseJson },
|
|
{ "torrent_get tr5 -> tr5", CurrentTorrentGetJson, Style::Tr5, CurrentTorrentGetJson },
|
|
{ "torrent_get tr5 -> tr4", CurrentTorrentGetJson, Style::Tr4, LegacyTorrentGetJson },
|
|
{ "torrent_get tr4 -> tr5", LegacyTorrentGetJson, Style::Tr5, CurrentTorrentGetJson },
|
|
{ "torrent_get tr4 -> tr4", LegacyTorrentGetJson, Style::Tr4, LegacyTorrentGetJson },
|
|
{ "port_test error response tr5 -> tr5", CurrentPortTestErrorResponse, Style::Tr5, CurrentPortTestErrorResponse },
|
|
{ "port_test error response tr5 -> tr4", CurrentPortTestErrorResponse, Style::Tr4, LegacyPortTestErrorResponse },
|
|
{ "port_test error response tr4 -> tr5", LegacyPortTestErrorResponse, Style::Tr5, CurrentPortTestErrorResponse },
|
|
{ "port_test error response tr4 -> tr4", LegacyPortTestErrorResponse, Style::Tr4, LegacyPortTestErrorResponse },
|
|
{ "bad method name tr5 -> tr5", BadMethodNameResponse, Style::Tr5, BadMethodNameResponse },
|
|
{ "bad method name tr5 -> tr4", BadMethodNameResponse, Style::Tr4, BadMethodNameLegacyResponse },
|
|
{ "bad method name tr4 -> tr5", BadMethodNameLegacyResponse, Style::Tr5, BadMethodNameResponse },
|
|
{ "bad method name tr4 -> tr4", BadMethodNameLegacyResponse, Style::Tr4, BadMethodNameLegacyResponse },
|
|
{ "unrecognised info tr5 -> tr5", UnrecognisedInfoResponse, Style::Tr5, UnrecognisedInfoResponse},
|
|
{ "unrecognised info tr5 -> tr4", UnrecognisedInfoResponse, Style::Tr4, UnrecognisedInfoLegacyResponse},
|
|
{ "unrecognised info tr4 -> tr5", UnrecognisedInfoLegacyResponse, Style::Tr5, UnrecognisedInfoResponse},
|
|
{ "unrecognised info tr4 -> tr4", UnrecognisedInfoLegacyResponse, Style::Tr4, UnrecognisedInfoLegacyResponse},
|
|
|
|
// TODO(ckerr): torrent-get with 'table'
|
|
} };
|
|
// clang-format on
|
|
|
|
for (auto const& [name, src, tgt_style, expected] : TestCases)
|
|
{
|
|
auto serde = tr_variant_serde::json();
|
|
auto parsed = serde.parse(src);
|
|
ASSERT_TRUE(parsed.has_value()) << name << ": " << serde.error_;
|
|
auto converted = libtransmission::api_compat::convert(*parsed, tgt_style);
|
|
EXPECT_EQ(expected, serde.to_string(converted)) << name;
|
|
}
|
|
}
|
|
|
|
TEST(ApiCompatTest, canConvertJsonDataFiles)
|
|
{
|
|
using Style = libtransmission::api_compat::Style;
|
|
using TestCase = std::tuple<std::string_view, std::string_view, Style, std::string_view>;
|
|
|
|
static auto constexpr TestCases = std::array<TestCase, 8U>{ {
|
|
{ "settings tr5 -> tr5", CurrentSettingsJson, Style::Tr5, CurrentSettingsJson },
|
|
{ "settings tr5 -> tr4", CurrentSettingsJson, Style::Tr4, LegacySettingsJson },
|
|
{ "settings tr4 -> tr5", LegacySettingsJson, Style::Tr5, CurrentSettingsJson },
|
|
{ "settings tr4 -> tr4", LegacySettingsJson, Style::Tr4, LegacySettingsJson },
|
|
|
|
{ "stats tr5 -> tr5", CurrentStatsJson, Style::Tr5, CurrentStatsJson },
|
|
{ "stats tr5 -> tr4", CurrentStatsJson, Style::Tr4, LegacyStatsJson },
|
|
{ "stats tr4 -> tr5", LegacyStatsJson, Style::Tr5, CurrentStatsJson },
|
|
{ "stats tr4 -> tr4", LegacyStatsJson, Style::Tr4, LegacyStatsJson },
|
|
} };
|
|
|
|
for (auto const& [name, src, tgt_style, expected] : TestCases)
|
|
{
|
|
auto serde = tr_variant_serde::json();
|
|
serde.inplace();
|
|
|
|
auto parsed = serde.parse(src);
|
|
ASSERT_TRUE(parsed.has_value());
|
|
auto converted = libtransmission::api_compat::convert(*parsed, tgt_style);
|
|
EXPECT_EQ(expected, serde.to_string(converted)) << name;
|
|
}
|
|
}
|
|
|
|
TEST(ApiCompatTest, canConvertBencDataFiles)
|
|
{
|
|
using Style = libtransmission::api_compat::Style;
|
|
using TestCase = std::tuple<std::string_view, std::string_view, Style, std::string_view>;
|
|
|
|
static auto constexpr TestCases = std::array<TestCase, 4U>{ {
|
|
{ "resume tr5 -> tr5", ResumeBenc, Style::Tr5, ResumeBenc },
|
|
{ "resume tr5 -> tr4", ResumeBenc, Style::Tr4, LegacyResumeBenc },
|
|
{ "resume tr4 -> tr5", LegacyResumeBenc, Style::Tr5, ResumeBenc },
|
|
{ "resume tr4 -> tr4", LegacyResumeBenc, Style::Tr4, LegacyResumeBenc },
|
|
} };
|
|
|
|
for (auto const& [name, src, tgt_style, expected] : TestCases)
|
|
{
|
|
auto serde = tr_variant_serde::benc();
|
|
serde.inplace();
|
|
|
|
auto parsed = serde.parse(src);
|
|
ASSERT_TRUE(parsed.has_value()) << name;
|
|
auto converted = libtransmission::api_compat::convert(*parsed, tgt_style);
|
|
EXPECT_EQ(expected, serde.to_string(converted)) << name;
|
|
}
|
|
}
|