chore: initial sanitized public snapshot
This commit is contained in:
@@ -0,0 +1,420 @@
|
||||
use super::*;
|
||||
|
||||
#[expect(
|
||||
clippy::too_many_lines,
|
||||
reason = "segment-plan regression fixture keeps response bodies, ranges, and request assertions adjacent"
|
||||
)]
|
||||
#[test]
|
||||
fn execute_runtime_uses_segment_plan_after_bootstrap_partial_response() {
|
||||
let downloader = SequencedHttpDownloader::new(vec![
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "4".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 0-3/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"1234".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 0,
|
||||
end_inclusive: 3,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "4".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 4-7/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"5678".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 4,
|
||||
end_inclusive: 7,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "2".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 8-9/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"90".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 8,
|
||||
end_inclusive: 9,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
]);
|
||||
let temp_dir = std::env::temp_dir().join("aria2-rust-pro-cli-explicit-segments-test");
|
||||
let _ = fs::create_dir_all(&temp_dir);
|
||||
let config_path = temp_dir.join("aria2.conf");
|
||||
fs::write(
|
||||
&config_path,
|
||||
"max-tries=3\nsplit=3\nmin-split-size=4\npiece-length=4\n",
|
||||
)
|
||||
.expect("config should write");
|
||||
|
||||
let report = execute_runtime_with_downloader(
|
||||
Invocation::Run {
|
||||
config_path: Some(config_path.clone()),
|
||||
uris: vec!["http://example.com/segment-plan.bin".to_owned()],
|
||||
},
|
||||
&downloader,
|
||||
)
|
||||
.expect("runtime should execute via explicit segments");
|
||||
|
||||
assert_eq!(report.completed_download_count, 1);
|
||||
assert_eq!(report.first_status.as_deref(), Some("complete"));
|
||||
assert_eq!(report.first_completed_length, Some(10));
|
||||
|
||||
let recorded = downloader.recorded_requests();
|
||||
let [bootstrap, first_followup, second_followup] = recorded.as_slice() else {
|
||||
panic!("expected exactly three recorded requests");
|
||||
};
|
||||
assert_eq!(bootstrap.request.range, None);
|
||||
let mut followup_ranges = [first_followup, second_followup]
|
||||
.iter()
|
||||
.map(|task| task.request.range)
|
||||
.collect::<Vec<_>>();
|
||||
followup_ranges.sort_by_key(|range| range.as_ref().map(|range| range.start));
|
||||
assert_eq!(
|
||||
followup_ranges,
|
||||
vec![
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 4,
|
||||
end_inclusive: Some(9),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
}),
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 8,
|
||||
end_inclusive: Some(9),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
}),
|
||||
]
|
||||
);
|
||||
|
||||
let _ = fs::remove_file(config_path);
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::too_many_lines,
|
||||
reason = "initial range-probe regression keeps bootstrap and follow-up range fixtures adjacent"
|
||||
)]
|
||||
#[test]
|
||||
fn execute_runtime_uses_initial_range_probe_when_split_budget_allows_parallel_segments() {
|
||||
let downloader = SequencedHttpDownloader::new(vec![
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "4".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 0-3/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"1234".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 0,
|
||||
end_inclusive: 3,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "4".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 4-7/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"5678".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 4,
|
||||
end_inclusive: 7,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "2".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 8-9/10".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"90".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 8,
|
||||
end_inclusive: 9,
|
||||
total_size: Some(10),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
]);
|
||||
let temp_dir = std::env::temp_dir().join("aria2-rust-pro-cli-segment-probe-test");
|
||||
let _ = fs::create_dir_all(&temp_dir);
|
||||
let config_path = temp_dir.join("aria2.conf");
|
||||
fs::write(
|
||||
&config_path,
|
||||
"split=3\nmax-connection-per-server=3\nmin-split-size=4\npiece-length=4\n",
|
||||
)
|
||||
.expect("config should write");
|
||||
|
||||
let report = execute_runtime_with_downloader(
|
||||
Invocation::Run {
|
||||
config_path: Some(config_path.clone()),
|
||||
uris: vec!["http://example.com/probe-plan.bin".to_owned()],
|
||||
},
|
||||
&downloader,
|
||||
)
|
||||
.expect("runtime should execute via initial range probe");
|
||||
|
||||
assert_eq!(report.completed_download_count, 1);
|
||||
assert_eq!(report.first_status.as_deref(), Some("complete"));
|
||||
assert_eq!(report.first_completed_length, Some(10));
|
||||
|
||||
let recorded = downloader.recorded_requests();
|
||||
let [probe, first_followup, second_followup] = recorded.as_slice() else {
|
||||
panic!("expected exactly three recorded requests");
|
||||
};
|
||||
assert_eq!(
|
||||
probe.request.range,
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 0,
|
||||
end_inclusive: Some(3),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
})
|
||||
);
|
||||
let mut followup_ranges = [first_followup, second_followup]
|
||||
.iter()
|
||||
.map(|task| task.request.range)
|
||||
.collect::<Vec<_>>();
|
||||
followup_ranges.sort_by_key(|range| range.as_ref().map(|range| range.start));
|
||||
assert_eq!(
|
||||
followup_ranges,
|
||||
vec![
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 4,
|
||||
end_inclusive: Some(7),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
}),
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 8,
|
||||
end_inclusive: Some(9),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
}),
|
||||
]
|
||||
);
|
||||
|
||||
let _ = fs::remove_file(config_path);
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::too_many_lines,
|
||||
reason = "tiny-tail regression keeps the coalesced probe fixture next to the expected request ranges"
|
||||
)]
|
||||
#[test]
|
||||
fn execute_runtime_coalesces_tiny_followup_tail_after_initial_probe() {
|
||||
let downloader = SequencedHttpDownloader::new(vec![
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "32".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 0-31/36".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"1234567890abcdefghijklmnopqrstuv".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 0,
|
||||
end_inclusive: 31,
|
||||
total_size: Some(36),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
Ok(HttpResponseModel {
|
||||
status: 206,
|
||||
reason: "Partial Content".to_owned(),
|
||||
version: HttpVersion::Http11,
|
||||
headers: HttpResponseHeaders {
|
||||
headers: vec![
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-length".to_owned(),
|
||||
value: "4".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
aria2_rust_pro_protocol::HttpHeader {
|
||||
name: "content-range".to_owned(),
|
||||
value: "bytes 32-35/36".to_owned(),
|
||||
kind: aria2_rust_pro_protocol::HeaderKind::Response,
|
||||
},
|
||||
],
|
||||
},
|
||||
body: ResponseBody::Inline(b"ghij".to_vec()),
|
||||
content_range: Some(aria2_rust_pro_protocol::ContentRangeSpec {
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
start: 32,
|
||||
end_inclusive: 35,
|
||||
total_size: Some(36),
|
||||
unsatisfied: false,
|
||||
}),
|
||||
partial_content: true,
|
||||
checksum: None,
|
||||
redirected_from: None,
|
||||
}),
|
||||
]);
|
||||
let temp_dir = std::env::temp_dir().join("aria2-rust-pro-cli-tiny-tail-coalesce-test");
|
||||
let _ = fs::create_dir_all(&temp_dir);
|
||||
let config_path = temp_dir.join("aria2.conf");
|
||||
fs::write(
|
||||
&config_path,
|
||||
"split=4\nmax-connection-per-server=4\nmin-split-size=4\npiece-length=4\n",
|
||||
)
|
||||
.expect("config should write");
|
||||
|
||||
let report = execute_runtime_with_downloader(
|
||||
Invocation::Run {
|
||||
config_path: Some(config_path.clone()),
|
||||
uris: vec!["http://example.com/coalesced-tail.bin".to_owned()],
|
||||
},
|
||||
&downloader,
|
||||
)
|
||||
.expect("runtime should coalesce tiny follow-up tail after probe");
|
||||
|
||||
assert_eq!(report.completed_download_count, 1);
|
||||
assert_eq!(report.first_status.as_deref(), Some("complete"));
|
||||
assert_eq!(report.first_completed_length, Some(36));
|
||||
|
||||
let recorded = downloader.recorded_requests();
|
||||
let [probe, first_followup] = recorded.as_slice() else {
|
||||
panic!("expected exactly two recorded requests");
|
||||
};
|
||||
assert_eq!(
|
||||
probe.request.range,
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 0,
|
||||
end_inclusive: Some(31),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
first_followup.request.range,
|
||||
Some(aria2_rust_pro_protocol::RangeSpec {
|
||||
start: 32,
|
||||
end_inclusive: Some(35),
|
||||
unit: aria2_rust_pro_protocol::RangeUnit::Bytes,
|
||||
})
|
||||
);
|
||||
|
||||
let _ = fs::remove_file(config_path);
|
||||
}
|
||||
Reference in New Issue
Block a user