1
//! Test data, downloaded from the live network, and filtered to reduce its size
2
//!
3
//! The parsed forms obtained by [`netstatus_plain()`] etc.
4
//! have retained unknown values iff the `retain-unknown` cargo feature is enabled.
5

            
6
use paste::paste;
7

            
8
use crate::doc::microdesc::Microdesc;
9
use crate::doc::netstatus;
10
use crate::doc::routerdesc::{RouterDesc, RouterDescUnverified};
11
use crate::parse2::{NetdocParseable, NetdocParseableUnverified};
12
use crate::test_support::parse_test_document;
13

            
14
#[macro_use]
15
#[path = "../testdata-live/generated_consts.rs"]
16
#[rustfmt::skip] // shell script output is nice, but not 100% identical to rustfmt
17
mod generated_consts;
18

            
19
pub use generated_consts::*;
20

            
21
/// Three test data file contents', one per variety
22
#[derive(Clone, Debug)]
23
#[non_exhaustive]
24
pub struct PerVariety {
25
    /// Plain consensus
26
    pub plain: &'static str,
27

            
28
    /// Microdescriptor consensus
29
    pub md: &'static str,
30

            
31
    /// Vote
32
    pub vote: &'static str,
33
}
34

            
35
/// Test data for one (selected) relay
36
#[derive(Clone, Debug)]
37
#[non_exhaustive]
38
pub struct PerRelay {
39
    /// Nickname
40
    pub nick: &'static str,
41

            
42
    /// Data for this relay
43
    pub data: PerVariety,
44
}
45

            
46
// ---------- parsed documents ----------
47

            
48
/// Relay-specific parsed test document or fragment
49
///
50
/// Used for routerstatus entries in network statuses, and also
51
/// relay descriptors and microdescriptors.
52
#[derive(Debug, Clone, Copy)]
53
#[non_exhaustive]
54
pub struct RelayDocument<D: 'static> {
55
    /// Nickname
56
    pub nick: &'static str,
57

            
58
    /// Actual document
59
    pub doc: &'static D,
60
}
61

            
62
/// Parse and yield a `Vec<RelayDocument<_>>`
63
286
fn relay_documents<D, S>(inputs: &[PerRelay], selector: S) -> Vec<RelayDocument<D>>
64
286
where
65
286
    D: NetdocParseable + Sync,
66
286
    S: Fn(&PerVariety) -> &'static str,
67
{
68
286
    inputs
69
286
        .iter()
70
286
        .map(|relay| RelayDocument {
71
1430
            nick: relay.nick,
72
1430
            doc: parse_test_document::<D>(selector(&relay.data)),
73
1430
        })
74
        // We don't memoise the Vec; it has only about 5 elements of 3 words each
75
286
        .collect()
76
286
}
77

            
78
/// Turn a `Vec<RelayDocument<FooUnverified>>` into a `Vec<RelayDocument<Foo>>`
79
4
fn unwrap_bodies<U>(u: Vec<RelayDocument<U>>) -> Vec<RelayDocument<U::Body>>
80
4
where
81
4
    U: NetdocParseableUnverified,
82
{
83
4
    u.into_iter()
84
4
        .map(|rd| RelayDocument {
85
20
            nick: rd.nick,
86
20
            doc: rd.doc.inspect_unverified().0,
87
20
        })
88
4
        .collect()
89
4
}
90

            
91
/// Define `netstatus_V`, `netstatus_V_unverified` and `relay_routerstatuses_V`
92
//
93
// We could use the per variety macros but that seems even more confusing
94
macro_rules! netstatus_variety { { $v:ident } => { paste!{
95
    /// Parsed network status, in unverified form
96
66
    pub fn [<netstatus_ $v _unverified>]() -> &'static netstatus::$v::NetworkStatusUnverified {
97
66
        parse_test_document(NETSTATUS.$v)
98
66
    }
99
    /// Parsed network status
100
60
    pub fn [<netstatus_ $v>]() -> &'static netstatus::$v::NetworkStatus {
101
60
        [<netstatus_ $v _unverified>]().inspect_unverified().0
102
60
    }
103
    /// Parsed routerstatus entries
104
6
    pub fn [<relay_routerstatuses_ $v>]() -> Vec<RelayDocument<netstatus::$v::RouterStatus>> {
105
6
        relay_documents(RELAY_ROUTERSTATUSES, |relay| relay.$v)
106
6
    }
107
} } }
108

            
109
netstatus_variety! { plain }
110
netstatus_variety! { md }
111
netstatus_variety! { vote }
112

            
113
/// Router descriptors (as listed in the consensus)
114
2
pub fn relay_routerdescs() -> Vec<RelayDocument<RouterDesc>> {
115
2
    unwrap_bodies(relay_routerdescs_unverified())
116
2
}
117
/// Router descriptors (as listed in the consensus), in unverified form
118
4
pub fn relay_routerdescs_unverified() -> Vec<RelayDocument<RouterDescUnverified>> {
119
4
    relay_documents(RELAY_DESCRIPTORS, |relay| relay.plain)
120
4
}
121
/// Router descriptors (as listed in the vote)
122
2
pub fn relay_routerdescs_vote() -> Vec<RelayDocument<RouterDesc>> {
123
2
    unwrap_bodies(relay_routerdescs_vote_unverified())
124
2
}
125
/// Router descriptors (as listed in the consensus), in unverified form
126
4
pub fn relay_routerdescs_vote_unverified() -> Vec<RelayDocument<RouterDescUnverified>> {
127
4
    relay_documents(RELAY_DESCRIPTORS, |relay| relay.vote)
128
4
}
129
/// Microdescriptors as listed in the consensus
130
// Microdescs aren't signed so there is no relay_microdescs_unverified
131
272
pub fn relay_microdescs() -> Vec<RelayDocument<Microdesc>> {
132
272
    relay_documents(RELAY_DESCRIPTORS, |relay| relay.md)
133
272
}
134

            
135
/// Find a particular relay's document, given the relay's nickname
136
///
137
/// This is sound for `testdata_live` data, because we only have a small curated
138
/// subset of of relays, all of which have distinct nicks.
139
///
140
/// # Panics
141
///
142
/// Panics if no relay with the given name is found.
143
///
144
/// # Example
145
///
146
/// ```
147
/// use tor_netdoc::doc::microdesc::Microdesc;
148
/// use tor_netdoc::testdata_live::{relay_document_by_nick, relay_microdescs};
149
///
150
/// let _: &'static Microdesc = relay_document_by_nick("lisdex", &relay_microdescs());
151
/// ```
152
10
pub fn relay_document_by_nick<D>(nick: &str, docs: &[RelayDocument<D>]) -> &'static D {
153
30
    docs.iter().find(|d| d.nick == nick).expect(nick).doc
154
10
}
155

            
156
#[test]
157
2
fn test_all() {
158
2
    netstatus_plain();
159
2
    netstatus_md();
160
2
    netstatus_vote();
161

            
162
2
    netstatus_plain_unverified();
163
2
    netstatus_md_unverified();
164
2
    netstatus_vote_unverified();
165

            
166
2
    relay_routerstatuses_plain();
167
2
    relay_routerstatuses_md();
168
2
    relay_routerstatuses_vote();
169

            
170
2
    relay_routerdescs();
171
2
    relay_routerdescs_unverified();
172

            
173
2
    relay_routerdescs_vote();
174
2
    relay_routerdescs_vote_unverified();
175

            
176
2
    relay_microdescs();
177
2
}