diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2023-09-07 10:41:30 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2023-09-18 10:33:05 +0100 |
commit | c048a3e21334cc46b0035c5083516652b0031465 (patch) | |
tree | f7a0c1606323e180a2305ee9ae571c0460f2baf0 | |
parent | 9083d6a38430a79de7e57bc99716354b8f604636 (diff) | |
download | arti-c048a3e21334cc46b0035c5083516652b0031465.tar.gz arti-c048a3e21334cc46b0035c5083516652b0031465.zip |
tor-hsservice: ipt_set: Add some tests
-rw-r--r-- | crates/tor-hsservice/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/tor-hsservice/src/ipt_set.rs | 117 |
2 files changed, 118 insertions, 0 deletions
diff --git a/crates/tor-hsservice/Cargo.toml b/crates/tor-hsservice/Cargo.toml index 051dffeed..dd98c068d 100644 --- a/crates/tor-hsservice/Cargo.toml +++ b/crates/tor-hsservice/Cargo.toml @@ -69,4 +69,5 @@ void = "1" [dev-dependencies] humantime = "2" serde_json = "1.0.104" +tor-netdoc = { path = "../tor-netdoc", version = "0.8.3", features = ["testing"] } tor-rtmock = { path = "../tor-rtmock", version = "0.9.1" } diff --git a/crates/tor-hsservice/src/ipt_set.rs b/crates/tor-hsservice/src/ipt_set.rs index 12d818d67..62273d0ae 100644 --- a/crates/tor-hsservice/src/ipt_set.rs +++ b/crates/tor-hsservice/src/ipt_set.rs @@ -9,6 +9,7 @@ use futures::channel::mpsc; use futures::StreamExt as _; use derive_more::{Deref, DerefMut}; +use itertools::chain; use crate::FatalError; use crate::IptLocalId; @@ -282,3 +283,119 @@ impl IptSet { Ok(()) } } + +#[cfg(test)] +mod test { + // @@ begin test lint list maintained by maint/add_warning @@ + #![allow(clippy::bool_assert_comparison)] + #![allow(clippy::clone_on_copy)] + #![allow(clippy::dbg_macro)] + #![allow(clippy::print_stderr)] + #![allow(clippy::print_stdout)] + #![allow(clippy::single_char_pattern)] + #![allow(clippy::unwrap_used)] + #![allow(clippy::unchecked_duration_subtraction)] + #![allow(clippy::useless_vec)] + #![allow(clippy::needless_pass_by_value)] + //! <!-- @@ end test lint list maintained by maint/add_warning @@ --> + use super::*; + use futures::{pin_mut, poll}; + use std::task::Poll::{self, *}; + use tor_rtcompat::{BlockOn as _, SleepProvider as _}; + + fn test_intro_point() -> Ipt { + use tor_netdoc::doc::hsdesc::test_data; + test_data::test_parsed_hsdesc().unwrap().intro_points()[0].clone() + } + + async fn pv_poll_await_update( + pv: &mut IptsPublisherView, + ) -> Poll<Option<Result<(), FatalError>>> { + let fut = pv.await_update(); + pin_mut!(fut); + poll!(fut) + } + + async fn pv_expect_one_await_update(pv: &mut IptsPublisherView) { + assert!(matches!( + pv_poll_await_update(pv).await, + Ready(Some(Ok(()))) + )); + assert!(matches!(pv_poll_await_update(pv).await, Pending)); + } + + fn pv_note_publication_attempt(pv: &mut IptsPublisherView, worst_case_end: Instant) { + pv.borrow_for_publish() + .as_mut() + .unwrap() + .note_publication_attempt(worst_case_end) + .unwrap(); + } + + fn mv_get_0_expiry(mv: &mut IptsManagerView) -> Instant { + mv.borrow_for_update().as_ref().unwrap().ipts[0] + .last_descriptor_expiry_including_slop + .unwrap() + } + + #[test] + fn test() { + // We don't bother with MockRuntime::test_with_various + // since this test case doesn't spawn tasks + let runtime = tor_rtmock::MockRuntime::new(); + runtime.clone().block_on(async move { + // make a channel; it should have no updates yet + + let (mut mv, mut pv) = ipts_channel(None); + assert!(matches!(pv_poll_await_update(&mut pv).await, Pending)); + + // borrowing publisher view for publish doesn't cause an update + + let pg = pv.borrow_for_publish(); + assert!(pg.is_none()); + drop(pg); + + // borrowing manager view for update *does* cause one update + + let mut mg = mv.borrow_for_update(); + *mg = Some(IptSet { + ipts: vec![], + lifetime: Duration::ZERO, + }); + drop(mg); + + pv_expect_one_await_update(&mut pv).await; + + // borrowing manager view for update twice cause one update + + const LIFETIME: Duration = Duration::from_secs(1800); + const PUBLISH_END_TIMEOUT: Duration = Duration::from_secs(300); + + mv.borrow_for_update().as_mut().unwrap().lifetime = LIFETIME; + mv.borrow_for_update() + .as_mut() + .unwrap() + .ipts + .push(IptInSet { + ipt: test_intro_point(), + lid: IptLocalId([42; 32]), + last_descriptor_expiry_including_slop: None, + }); + + pv_expect_one_await_update(&mut pv).await; + + // test setting lifetime + + pv_note_publication_attempt(&mut pv, runtime.now() + PUBLISH_END_TIMEOUT); + + let expected_expiry = + runtime.now() + PUBLISH_END_TIMEOUT + LIFETIME + IPT_PUBLISH_EXPIRY_SLOP; + assert_eq!(mv_get_0_expiry(&mut mv), expected_expiry); + + // setting an *earlier* lifetime is ignored + + pv_note_publication_attempt(&mut pv, runtime.now() - Duration::from_secs(10)); + assert_eq!(mv_get_0_expiry(&mut mv), expected_expiry); + }); + } +} |