chore: initial sanitized public snapshot

This commit is contained in:
Aria2 Rust Pro Contributors
2026-07-18 14:51:59 +08:00
commit 14dcf8c9bf
321 changed files with 76893 additions and 0 deletions
@@ -0,0 +1,317 @@
#![expect(
missing_docs,
reason = "integration test scenarios are documented by case names rather than item-level rustdoc"
)]
use std::collections::BTreeMap;
use aria2_rust_pro_cli as _;
use aria2_rust_pro_compat as _;
use aria2_rust_pro_core as _;
use aria2_rust_pro_protocol::{
DhtMessageModel, TrackerRequestModel, TrackerTransport,
torrent::{
DhtMessageBody, DhtQueryModel, PeerWireBitfieldModel, PeerWireMessageKind,
PeerWirePieceBlockModel,
},
};
use aria2_rust_pro_rpc::{InProcessRpcDispatcher, RpcMethod, RpcValue};
use aria2_rust_pro_storage as _;
use aria2_rust_pro_tests as _;
use criterion as _;
#[path = "../test_support/support.rs"]
mod support;
#[test]
#[expect(
clippy::too_many_lines,
reason = "integration scenario keeps one end-to-end bt surface in a single readable flow"
)]
fn tracker_dht_peer_wire_and_seeding_updates_remain_rpc_visible_across_public_dispatcher_api() {
let tracker_server =
support::LocalTrackerServer::spawn(support::compact_peer([198, 51, 100, 9], 51413), 900);
let tracker = support::tracker_transport();
let mut dispatcher = InProcessRpcDispatcher::new();
let gid = support::add_torrent(&mut dispatcher);
let bootstrap_status =
support::rpc_result_object(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2TellStatus,
vec![RpcValue::String(gid.clone())],
)));
let info_hash = support::rpc_string_field(&bootstrap_status, "infoHash");
let magnet_uri = support::rpc_string_field(&bootstrap_status, "magnetUri");
let announce = tracker
.announce(&TrackerRequestModel {
announce_url: tracker_server.announce_url().to_owned(),
info_hash: info_hash.clone(),
peer_id: "0123456789abcdef0123456789abcdef01234567".to_owned(),
port: 6881,
uploaded: 0,
downloaded: 0,
left: 32_768,
event: Some("started".to_owned()),
compact: true,
numwant: Some(10),
})
.expect("live tracker announce should succeed");
dispatcher
.apply_tracker_announce_result(&gid, &announce)
.expect("tracker announce should update the bt view");
let dht_get_peers = support::RecordingDhtTransport::new(DhtMessageModel::get_peers_response(
b"gp".to_vec(),
vec![0x55; 20],
Some(b"dht-token".to_vec()),
Some(support::compact_node(0x44, [203, 0, 113, 99], 51414)),
vec![support::compact_peer([198, 51, 100, 10], 51415)],
));
dispatcher
.execute_dht_get_peers(&gid, &dht_get_peers)
.expect("dht get_peers should succeed");
let dht_find_node = support::RecordingDhtTransport::new(DhtMessageModel::find_node_response(
b"fn".to_vec(),
vec![0x66; 20],
vec![aria2_rust_pro_protocol::torrent::DhtCompactNodeModel {
node_id: [0x77; 20],
address: [203, 0, 113, 100],
port: 51416,
}],
));
dispatcher
.execute_dht_find_node(&gid, &dht_find_node)
.expect("dht find_node should succeed");
let dht_announce = support::RecordingDhtTransport::new(DhtMessageModel::ping_response(
b"ap".to_vec(),
vec![0x88; 20],
));
dispatcher
.execute_dht_announce_peer(&gid, &dht_announce)
.expect("dht announce_peer should succeed after token handoff");
let info_hash_bytes = support::decode_hex_20(&info_hash);
let remote_peer_id = *b"-AZ2060-MODERN-PEER!";
let connector = support::FakePeerWireConnector::new(support::peer_wire_handshake_and_frames(
info_hash_bytes,
remote_peer_id,
&[
PeerWireMessageKind::Unchoke,
PeerWireMessageKind::Bitfield(PeerWireBitfieldModel::from_piece_flags(&[true, true])),
PeerWireMessageKind::Piece(PeerWirePieceBlockModel {
piece_index: 0,
block_offset: 0,
block: vec![0x5a; 16_384],
}),
],
));
dispatcher
.execute_peer_wire_exchange(&gid, &connector)
.expect("peer-wire exchange should succeed");
dispatcher
.apply_bt_runtime_tick(&gid, 16_384, 0, 512, 0, 0, 0, false, Some(8))
.expect("runtime tick should finish the remaining payload");
dispatcher
.set_bt_seeding_state(&gid, true, Some(1_000))
.expect("completed torrent should enter seeding");
dispatcher
.tick_bt_runtime_clock(&gid, 1_030, true)
.expect("share clock should advance");
dispatcher
.apply_bt_runtime_tick(&gid, 0, 16_384, 90, 180, 5, 5, true, Some(8))
.expect("upload tick should populate visible share fields");
let _ = dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2ChangeOption,
vec![
RpcValue::String(gid.clone()),
RpcValue::Object(BTreeMap::from([(
"select-file".to_owned(),
RpcValue::String("1".to_owned()),
)])),
],
));
let status = support::rpc_result_object(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2TellStatus,
vec![RpcValue::String(gid.clone())],
)));
assert!(support::rpc_bool_field(&status, "isBt"));
assert!(!support::rpc_bool_field(&status, "metadataOnly"));
assert_eq!(support::rpc_string_field(&status, "magnetUri"), magnet_uri);
assert_eq!(support::rpc_u64_field(&status, "completedLength"), 32_768);
assert_eq!(support::rpc_u64_field(&status, "connections"), 8);
assert_eq!(support::rpc_string_field(&status, "shareRatio"), "0.500");
assert_eq!(support::rpc_u64_field(&status, "shareTime"), 35);
assert!(support::rpc_bool_field(&status, "seeder"));
assert_eq!(support::rpc_u64_field(&status, "numSeeders"), 1);
let files = support::rpc_result_array(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2GetFiles,
vec![RpcValue::String(gid.clone())],
)));
match files.first() {
Some(RpcValue::Object(file)) => {
assert_eq!(
file.get("selected"),
Some(&RpcValue::String("true".to_owned()))
);
assert_eq!(
file.get("path"),
Some(&RpcValue::String("ubuntu.iso".to_owned()))
);
}
other => panic!("unexpected file payload after bt orchestration: {other:?}"),
}
let peers = support::rpc_result_array(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2GetPeers,
vec![RpcValue::String(gid.clone())],
)));
match peers.first() {
Some(RpcValue::Object(peer)) => {
assert_eq!(
peer.get("peerId"),
Some(&RpcValue::String(
"2d415a323036302d4d4f4445524e2d5045455221".to_owned()
))
);
assert_eq!(
peer.get("peerChoking"),
Some(&RpcValue::String("false".to_owned()))
);
assert_eq!(
peer.get("seeder"),
Some(&RpcValue::String("true".to_owned()))
);
}
other => panic!("unexpected peer payload after bt orchestration: {other:?}"),
}
let seen_announce = dht_announce.seen();
assert_eq!(
seen_announce.len(),
1,
"announce_peer should send exactly one query"
);
match &seen_announce
.first()
.expect("announce_peer should record one query")
.1
.body
{
DhtMessageBody::Query(DhtQueryModel::AnnouncePeer(query)) => {
assert_eq!(query.info_hash, info_hash_bytes);
assert_eq!(query.token, b"dht-token".to_vec());
assert_eq!(query.port, 6881);
}
other => panic!("unexpected announce_peer query payload: {other:?}"),
}
let seen_peer_wire = connector.seen();
assert_eq!(
seen_peer_wire.len(),
1,
"peer-wire transport should see one request"
);
assert!(
seen_peer_wire
.first()
.expect("peer-wire transport should record one request")
.payload
.len()
> 68,
"peer-wire request should include the handshake plus follow-up frames"
);
}
#[test]
fn bt_status_surfaces_remain_monotonic_under_public_runtime_tick_pressure() {
let mut dispatcher = InProcessRpcDispatcher::new();
let gid = support::add_torrent(&mut dispatcher);
let mut last_completed = 0_u64;
let mut last_share_time = 0_u64;
for round in 0..48_u64 {
let downloaded_delta = if round < 16 { 2_048 } else { 0 };
let uploaded_delta = if round >= 16 { 512 } else { 0 };
let seeding = round >= 16;
dispatcher
.apply_bt_runtime_tick(
&gid,
downloaded_delta,
uploaded_delta,
256 + round,
128 + round,
u64::from(seeding),
u64::from(seeding),
seeding,
Some(2 + u32::try_from(round % 5).expect("round modulo 5 should fit u32")),
)
.expect("runtime tick should succeed under repeated probing");
if round == 16 {
dispatcher
.set_bt_seeding_state(&gid, true, Some(2_000))
.expect("completed torrent should enter seeding");
}
if seeding {
dispatcher
.tick_bt_runtime_clock(&gid, 2_000 + round, true)
.expect("runtime clock should advance while seeding");
}
let status = support::rpc_result_object(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2TellStatus,
vec![
RpcValue::String(gid.clone()),
RpcValue::Array(vec![
RpcValue::String("status".to_owned()),
RpcValue::String("completedLength".to_owned()),
RpcValue::String("connections".to_owned()),
RpcValue::String("files".to_owned()),
RpcValue::String("bitfield".to_owned()),
RpcValue::String("isBt".to_owned()),
RpcValue::String("shareRatio".to_owned()),
RpcValue::String("shareTime".to_owned()),
RpcValue::String("seeder".to_owned()),
]),
],
)));
let completed = support::rpc_u64_field(&status, "completedLength");
let share_time = support::rpc_u64_field(&status, "shareTime");
assert!(support::rpc_bool_field(&status, "isBt"));
assert!(
completed >= last_completed,
"completedLength should stay monotonic under repeated probes"
);
assert!(
share_time >= last_share_time,
"shareTime should stay monotonic under repeated probes"
);
assert!(
status.contains_key("bitfield"),
"bt tellStatus should retain bitfield visibility under pressure"
);
assert!(
status.contains_key("files"),
"bt tellStatus should retain files visibility under pressure"
);
last_completed = completed;
last_share_time = share_time;
let files = support::rpc_result_array(dispatcher.dispatch_json(support::rpc_request(
RpcMethod::Aria2GetFiles,
vec![RpcValue::String(gid.clone())],
)));
assert_eq!(files.len(), 1, "torrent fixture should expose one file");
match files.first() {
Some(RpcValue::Object(file)) => {
assert!(file.contains_key("selected"));
assert!(file.contains_key("completedLength"));
}
other => panic!("unexpected getFiles payload under pressure: {other:?}"),
}
}
}