tor_circmgr/path/
dirpath.rs
1use super::TorPath;
3use crate::Result;
4use tor_guardmgr::{GuardMgr, GuardMonitor, GuardUsable};
5use tor_rtcompat::Runtime;
6
7#[non_exhaustive]
9pub(crate) struct DirPathBuilder {}
10
11impl Default for DirPathBuilder {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl DirPathBuilder {
18 pub(crate) fn new() -> Self {
20 DirPathBuilder {}
21 }
22
23 pub(crate) fn pick_path<'a, RT: Runtime>(
26 &self,
27 guards: &GuardMgr<RT>,
28 ) -> Result<(TorPath<'a>, GuardMonitor, GuardUsable)> {
29 let guard_usage = tor_guardmgr::GuardUsageBuilder::default()
30 .kind(tor_guardmgr::GuardUsageKind::OneHopDirectory)
31 .build()
32 .expect("Unable to build directory guard usage");
33 let (guard, mon, usable) = guards.select_guard(guard_usage)?;
34 Ok((TorPath::new_one_hop_owned(&guard), mon, usable))
35 }
36}
37
38#[cfg(test)]
39mod test {
40 #![allow(clippy::bool_assert_comparison)]
42 #![allow(clippy::clone_on_copy)]
43 #![allow(clippy::dbg_macro)]
44 #![allow(clippy::mixed_attributes_style)]
45 #![allow(clippy::print_stderr)]
46 #![allow(clippy::print_stdout)]
47 #![allow(clippy::single_char_pattern)]
48 #![allow(clippy::unwrap_used)]
49 #![allow(clippy::unchecked_duration_subtraction)]
50 #![allow(clippy::useless_vec)]
51 #![allow(clippy::needless_pass_by_value)]
52 use super::*;
55 use std::collections::HashSet;
56 use tor_guardmgr::TestConfig;
57 use tor_linkspec::RelayIds;
58 use tor_netdir::testnet;
59 use tor_persist::TestingStateMgr;
60
61 #[test]
62 fn dirpath() {
63 tor_rtcompat::test_with_all_runtimes!(|rt| async move {
64 let netdir = testnet::construct_netdir().unwrap_if_sufficient().unwrap();
65 let statemgr = TestingStateMgr::new();
66 let guards =
67 tor_guardmgr::GuardMgr::new(rt.clone(), statemgr, &TestConfig::default()).unwrap();
68 guards.install_test_netdir(&netdir);
69
70 let mut distinct_guards = HashSet::new();
71
72 for _ in 0..40 {
75 let (path, mon, usable) = DirPathBuilder::new().pick_path(&guards).unwrap();
76 if let crate::path::TorPathInner::OwnedOneHop(relay) = path.inner {
77 distinct_guards.insert(RelayIds::from_relay_ids(&relay));
78 mon.succeeded();
79 assert!(usable.await.unwrap());
80 } else {
81 panic!("Generated the wrong kind of path.");
82 }
83 }
84 assert_eq!(
85 distinct_guards.len(),
86 netdir.params().guard_dir_use_parallelism.get() as usize
87 );
88 });
89 }
90}