Skip to content

Commit ae03809

Browse files
committed
test: cover every public TLS error contract
1 parent a5f3219 commit ae03809

1 file changed

Lines changed: 203 additions & 0 deletions

File tree

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#![allow(clippy::expect_used)]
2+
3+
use std::error::Error;
4+
use std::io;
5+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
6+
use std::time::Duration;
7+
8+
use originweave_core::Origin;
9+
use originweave_tls::TlsError;
10+
11+
fn rustls_error(label: &str) -> rustls::Error {
12+
rustls::Error::General(label.to_owned())
13+
}
14+
15+
fn io_error(kind: io::ErrorKind) -> io::Error {
16+
io::Error::from(kind)
17+
}
18+
19+
#[test]
20+
fn every_public_error_has_deterministic_display_and_source_semantics() {
21+
let https_origin = Origin::parse("https://example.com").expect("HTTPS origin");
22+
let other_origin = Origin::parse("https://other.example").expect("other HTTPS origin");
23+
let peer = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 443);
24+
let other_peer = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8443);
25+
let errors = vec![
26+
(TlsError::InvalidTrustBundleIdentifier, false),
27+
(
28+
TlsError::InvalidTrustRootCount {
29+
root_count: 0,
30+
maximum_count: 256,
31+
},
32+
false,
33+
),
34+
(
35+
TlsError::InvalidTrustRootBytes {
36+
byte_count: 3_000_000,
37+
maximum_bytes: 2_097_152,
38+
},
39+
false,
40+
),
41+
(
42+
TlsError::InvalidTrustRoot {
43+
root_index: 2,
44+
source: rustls_error("invalid root"),
45+
},
46+
true,
47+
),
48+
(
49+
TlsError::InvalidHandshakeTimeout {
50+
timeout: Duration::ZERO,
51+
maximum_timeout: Duration::from_secs(30),
52+
},
53+
false,
54+
),
55+
(
56+
TlsError::InvalidAlpnCount {
57+
protocol_count: 9,
58+
maximum_count: 8,
59+
},
60+
false,
61+
),
62+
(
63+
TlsError::InvalidAlpnIdentifier {
64+
protocol_index: 1,
65+
protocol_length: 0,
66+
maximum_length: 255,
67+
},
68+
false,
69+
),
70+
(
71+
TlsError::DuplicateAlpnIdentifier { protocol_index: 2 },
72+
false,
73+
),
74+
(
75+
TlsError::InvalidAlpnBytes {
76+
byte_count: 1_100,
77+
maximum_bytes: 1_024,
78+
},
79+
false,
80+
),
81+
(
82+
TlsError::OriginRequiresHttps {
83+
origin: https_origin.clone(),
84+
},
85+
false,
86+
),
87+
(
88+
TlsError::InvalidReferenceIdentity {
89+
origin: https_origin.clone(),
90+
},
91+
false,
92+
),
93+
(
94+
TlsError::TransportOriginMismatch {
95+
tls_origin: https_origin.clone(),
96+
transport_origin: other_origin,
97+
},
98+
false,
99+
),
100+
(
101+
TlsError::InheritedPeerMismatch {
102+
requested_peer: peer,
103+
observed_peer: peer,
104+
current_peer: other_peer,
105+
},
106+
false,
107+
),
108+
(
109+
TlsError::PeerInspectionFailed {
110+
expected_peer: peer,
111+
source: io_error(io::ErrorKind::NotConnected),
112+
},
113+
true,
114+
),
115+
(
116+
TlsError::TlsConfigurationFailed {
117+
source: rustls_error("configuration"),
118+
},
119+
true,
120+
),
121+
(
122+
TlsError::HandshakeTimedOut {
123+
timeout: Duration::from_secs(3),
124+
},
125+
false,
126+
),
127+
(
128+
TlsError::HandshakeIoFailed {
129+
source: io_error(io::ErrorKind::ConnectionReset),
130+
},
131+
true,
132+
),
133+
(
134+
TlsError::UnknownIssuer {
135+
source: rustls_error("unknown issuer"),
136+
},
137+
true,
138+
),
139+
(
140+
TlsError::CertificateExpired {
141+
source: rustls_error("expired"),
142+
},
143+
true,
144+
),
145+
(
146+
TlsError::CertificateNotYetValid {
147+
source: rustls_error("future"),
148+
},
149+
true,
150+
),
151+
(
152+
TlsError::ServiceIdentityMismatch {
153+
source: rustls_error("name mismatch"),
154+
},
155+
true,
156+
),
157+
(
158+
TlsError::InvalidCertificate {
159+
source: rustls_error("invalid certificate"),
160+
},
161+
true,
162+
),
163+
(
164+
TlsError::TlsProtocolFailed {
165+
source: rustls_error("protocol"),
166+
},
167+
true,
168+
),
169+
(TlsError::MissingProtocolVersion, false),
170+
(TlsError::UnsupportedProtocolVersion, false),
171+
(TlsError::MissingCipherSuite, false),
172+
(TlsError::AlpnRequired, false),
173+
(TlsError::UnexpectedAlpn, false),
174+
(TlsError::MissingPeerCertificates, false),
175+
(
176+
TlsError::ExcessivePeerCertificateCount {
177+
certificate_count: 17,
178+
maximum_count: 16,
179+
},
180+
false,
181+
),
182+
(
183+
TlsError::ExcessivePeerCertificateBytes {
184+
byte_count: 1_100_000,
185+
maximum_bytes: 1_048_576,
186+
},
187+
false,
188+
),
189+
(TlsError::InvalidLeafCertificate, false),
190+
(
191+
TlsError::TimeoutRestorationFailed {
192+
source: io_error(io::ErrorKind::InvalidInput),
193+
},
194+
true,
195+
),
196+
];
197+
198+
for (error, has_source) in errors {
199+
let message = error.to_string();
200+
assert!(!message.is_empty(), "{error:?}");
201+
assert_eq!(error.source().is_some(), has_source, "{error:?}");
202+
}
203+
}

0 commit comments

Comments
 (0)