mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
aquatic_http_protocol: add test for Request serde, fix Request.write bug
This commit is contained in:
parent
2893fffd20
commit
1b2b4f0eb5
2 changed files with 99 additions and 6 deletions
|
|
@ -61,13 +61,39 @@ impl FromStr for AnnounceEvent {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl quickcheck::Arbitrary for InfoHash {
|
impl quickcheck::Arbitrary for InfoHash {
|
||||||
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
|
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
|
||||||
let mut arr = [b'x'; 20];
|
let mut arr = [b'0'; 20];
|
||||||
|
|
||||||
arr[0] = u8::arbitrary(g);
|
for byte in arr.iter_mut(){
|
||||||
arr[1] = u8::arbitrary(g);
|
*byte = u8::arbitrary(g);
|
||||||
arr[18] = u8::arbitrary(g);
|
}
|
||||||
arr[19] = u8::arbitrary(g);
|
|
||||||
|
|
||||||
Self(arr)
|
Self(arr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl quickcheck::Arbitrary for PeerId {
|
||||||
|
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
|
||||||
|
let mut arr = [b'0'; 20];
|
||||||
|
|
||||||
|
for byte in arr.iter_mut(){
|
||||||
|
*byte = u8::arbitrary(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
impl quickcheck::Arbitrary for AnnounceEvent {
|
||||||
|
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
|
||||||
|
match (bool::arbitrary(g), bool::arbitrary(g)){
|
||||||
|
(false, false) => Self::Started,
|
||||||
|
(true, false) => Self::Started,
|
||||||
|
(false, true) => Self::Completed,
|
||||||
|
(true, true) => Self::Empty,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ impl AnnounceRequest {
|
||||||
urlencode_20_bytes(self.info_hash.0, output)?;
|
urlencode_20_bytes(self.info_hash.0, output)?;
|
||||||
|
|
||||||
output.write_all(b"&peer_id=")?;
|
output.write_all(b"&peer_id=")?;
|
||||||
urlencode_20_bytes(self.info_hash.0, output)?;
|
urlencode_20_bytes(self.peer_id.0, output)?;
|
||||||
|
|
||||||
output.write_all(b"&port=")?;
|
output.write_all(b"&port=")?;
|
||||||
output.write_all(itoa::Buffer::new().format(self.port).as_bytes())?;
|
output.write_all(itoa::Buffer::new().format(self.port).as_bytes())?;
|
||||||
|
|
@ -269,6 +269,8 @@ impl Request {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use quickcheck::{Arbitrary, Gen, TestResult, quickcheck};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
static ANNOUNCE_REQUEST_PATH: &str = "/announce?info_hash=%04%0bkV%3f%5cr%14%a6%b7%98%adC%c3%c9.%40%24%00%b9&peer_id=-ABC940-5ert69muw5t8&port=12345&uploaded=0&downloaded=0&left=1&numwant=0&key=4ab4b877&compact=1&supportcrypto=1&event=started";
|
static ANNOUNCE_REQUEST_PATH: &str = "/announce?info_hash=%04%0bkV%3f%5cr%14%a6%b7%98%adC%c3%c9.%40%24%00%b9&peer_id=-ABC940-5ert69muw5t8&port=12345&uploaded=0&downloaded=0&left=1&numwant=0&key=4ab4b877&compact=1&supportcrypto=1&event=started";
|
||||||
|
|
@ -318,4 +320,69 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(parsed_request, reference_request);
|
assert_eq!(parsed_request, reference_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for AnnounceRequest {
|
||||||
|
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||||
|
let key: Option<String> = Arbitrary::arbitrary(g);
|
||||||
|
|
||||||
|
AnnounceRequest {
|
||||||
|
info_hash: Arbitrary::arbitrary(g),
|
||||||
|
peer_id: Arbitrary::arbitrary(g),
|
||||||
|
port: Arbitrary::arbitrary(g),
|
||||||
|
bytes_left: Arbitrary::arbitrary(g),
|
||||||
|
event: Arbitrary::arbitrary(g),
|
||||||
|
compact: true,
|
||||||
|
numwant: Arbitrary::arbitrary(g),
|
||||||
|
key: key.map(|key| key.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for ScrapeRequest {
|
||||||
|
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||||
|
ScrapeRequest {
|
||||||
|
info_hashes: Arbitrary::arbitrary(g),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Request {
|
||||||
|
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||||
|
if Arbitrary::arbitrary(g){
|
||||||
|
Self::Announce(Arbitrary::arbitrary(g))
|
||||||
|
} else {
|
||||||
|
Self::Scrape(Arbitrary::arbitrary(g))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn quickcheck_serde_identity_request(){
|
||||||
|
fn prop(request: Request) -> TestResult {
|
||||||
|
if let Request::Announce(AnnounceRequest { key: Some(ref key), ..}) = request {
|
||||||
|
if !key.is_ascii(){
|
||||||
|
// Only ascii allowed in headers
|
||||||
|
return TestResult::discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
request.write(&mut bytes).unwrap();
|
||||||
|
|
||||||
|
let parsed_request = Request::from_bytes(&bytes[..]).unwrap();
|
||||||
|
|
||||||
|
let success = request == parsed_request;
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
println!("request: {:?}", request);
|
||||||
|
println!("parsed request: {:?}", parsed_request);
|
||||||
|
println!("bytes as str: {}", String::from_utf8_lossy(&bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
TestResult::from_bool(success)
|
||||||
|
}
|
||||||
|
|
||||||
|
quickcheck(prop as fn(Request) -> TestResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue