use super::*;
use std::time::Duration;
#[test]
fn boundary_collision_is_retried_and_random_failure_is_returned() {
let payload = format!("binary\0qgt-{}\r\n", "00".repeat(16));
let mut attempts = 0;
let boundary = boundary_with(payload.as_bytes(), |out| {
out.fill(attempts);
attempts += 1;
Ok(())
})
.unwrap();
assert_eq!(attempts, 2);
assert_eq!(boundary, format!("qgt-{}", "01".repeat(16)));
assert_eq!(
boundary_with(b"", |_| Err(Error::Random)),
Err(Error::Random)
);
}
#[test]
fn filename_uses_tqsls_utc_format() {
for (seconds, expected) in [
(0, "19700101-0000"),
(951_827_696, "20000229-1234"),
(4_107_542_400, "21000301-0000"),
] {
assert_eq!(
filename(UNIX_EPOCH + Duration::from_secs(seconds), "log.tq8"),
format!("<TQSLUpl {expected}> log.tq8")
);
}
assert_eq!(
filename(UNIX_EPOCH - Duration::from_secs(1), "log.tq8"),
filename(UNIX_EPOCH, "log.tq8")
);
}
#[test]
fn an_upload_is_named_by_its_file_and_never_its_folder() {
assert_eq!(upload_name("us12223.tq8"), "us12223.tq8");
assert_eq!(upload_name("/Users/someone/logs/us7831.tq8"), "us7831.tq8");
assert_eq!(upload_name("C:\\Logs\\Field Day.TQ8"), "Field_Day.TQ8");
assert_eq!(upload_name("contest.adi"), "contest.adi.tq8");
assert_eq!(upload_name("a\"b\r\nX: y.tq8"), "a_b__X__y.tq8");
assert_eq!(upload_name(""), "log.tq8");
assert_eq!(upload_name("/logs/"), "log.tq8");
assert_eq!(upload_name(".."), "log.tq8");
assert_eq!(upload_name(&"x".repeat(200)).len(), 64 + 4);
}
#[test]
fn a_named_upload_sends_that_name() {
let request =
super::UploadRequest::try_named(b"signed", "/home/someone/us12223.tq8").expect("request");
let head = String::from_utf8_lossy(request.body()).to_string();
assert!(head.contains("> us12223.tq8\"\r\n"), "{head}");
assert!(!head.contains("someone"), "{head}");
}
#[test]
fn only_a_signed_log_is_one_to_upload() {
use super::{NotASignedLog, check_signed_log};
let corpus = |f: &str| {
std::fs::read(
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/corpus/standard")
.join(f),
)
.expect(f)
};
let tq7 = corpus("signed/W4W-EVENT.tq7");
let tq8 = crate::signed_log::tq8(&tq7);
assert_eq!(check_signed_log(&tq8), Ok(tq8.clone()));
let mut commented = tq8[..10].to_vec();
commented[3] |= 0x10; commented.extend_from_slice(b"-----BEGIN PRIVATE KEY-----MIIC-----END PRIVATE KEY-----\0");
commented.extend_from_slice(&tq8[10..]);
let sent = check_signed_log(&commented).expect("the log itself is a signed log");
assert_eq!(sent, tq8);
assert!(!sent.windows(11).any(|w| w == b"PRIVATE KEY"));
let mut trailing = tq8.clone();
trailing.extend_from_slice(b"-----BEGIN PRIVATE KEY-----");
if let Ok(sent) = check_signed_log(&trailing) {
assert_eq!(sent, tq8);
}
assert_eq!(
check_signed_log(&corpus("standard.tbk")),
Err(NotASignedLog)
);
assert_eq!(check_signed_log(&tq7), Err(NotASignedLog));
assert_eq!(
check_signed_log(&crate::signed_log::tq8(&corpus("adif/W4W-EVENT.adi"))),
Err(NotASignedLog)
);
let text = String::from_utf8(tq7.clone()).expect("text");
let header: String = text
.split("<Rec_Type:8>tCONTACT")
.next()
.expect("head")
.into();
assert_eq!(
check_signed_log(&crate::signed_log::tq8(header.as_bytes())),
Err(NotASignedLog)
);
let planted = |text: String| check_signed_log(&crate::signed_log::tq8(text.as_bytes()));
assert_eq!(
planted(text.replacen(
"<Rec_Type:8>tCONTACT",
"<Rec_Type:8>tCONTACT\n<PRIVATE_KEY:4>TEST",
1
)),
Err(NotASignedLog)
);
assert_eq!(
planted(format!(
"{text}\n-----BEGIN PRIVATE KEY-----\nMIIC\n-----END PRIVATE KEY-----\n"
)),
Err(NotASignedLog)
);
let start = text.find("<CERTIFICATE:").expect("certificate");
let end = start + text[start..].find("<eor>").expect("end");
assert_eq!(
planted(format!(
"{}<CERTIFICATE:8>TUlJQ2Rn{}",
&text[..start],
&text[end..]
)),
Err(NotASignedLog)
);
let pem = String::from_utf8(
std::fs::read(
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/corpus/pki/user-1024.key.pem"),
)
.expect("test key"),
)
.expect("text");
let sd = text.find("<SIGNDATA:").expect("signdata");
let sd_end = sd + text[sd..].find('\n').expect("line");
assert_eq!(
planted(format!(
"{}<SIGNDATA:{}>{pem}{}",
&text[..sd],
pem.len(),
&text[sd_end..]
)),
Err(NotASignedLog)
);
assert_eq!(
planted(format!(
"<TQSL_IDENT:4>TEST\n<Rec_Type:8>tCONTACT\n<SIGNDATA:{}>{pem}<eor>\n",
pem.len()
)),
Err(NotASignedLog)
);
let head = &text[..text.find("<Rec_Type:8>tCONTACT").expect("contact")];
let contact = &text[text.find("<Rec_Type:8>tCONTACT").expect("contact")..];
let contact = &contact[..contact.find("<eor>").expect("end") + 5];
let mut big = String::from(head);
for _ in 0..(crate::records::MAX_RECORDS + 1) {
big.push_str(contact);
big.push('\n');
}
assert!(planted(big).is_ok());
}