Skip to content

Commit 8119772

Browse files
authored
tap: Restore tap matching tests (#1042)
The tap tests were disabled in #568. This change restores these tests, updating them to use quickcheck v1.
1 parent 9318075 commit 8119772

3 files changed

Lines changed: 145 additions & 147 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,7 @@ dependencies = [
12401240
"linkerd2-proxy-api",
12411241
"pin-project",
12421242
"prost-types",
1243+
"quickcheck",
12431244
"rand",
12441245
"thiserror",
12451246
"tokio",

linkerd/proxy/tap/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ pin-project = "1"
3232
[dev-dependencies]
3333
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", branch = "main", features = ["arbitrary"] }
3434
prost-types = "0.7.0"
35+
quickcheck = { version = "1", default-features = false }

linkerd/proxy/tap/src/grpc/match_.rs

Lines changed: 143 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -310,150 +310,146 @@ impl TryFrom<observe_request::r#match::Http> for HttpMatch {
310310
}
311311
}
312312

313-
// #[cfg(test)]
314-
// mod tests {
315-
// use ipnet::{Ipv4Net, Ipv6Net};
316-
// use quickcheck::*;
317-
// use rand::Rng;
318-
// use std::collections::HashMap;
319-
320-
// use super::*;
321-
// use linkerd2_proxy_api::http_types;
322-
323-
// impl Arbitrary for LabelMatch {
324-
// fn arbitrary<G: Gen>(g: &mut G) -> Self {
325-
// Self {
326-
// key: Arbitrary::arbitrary(g),
327-
// value: Arbitrary::arbitrary(g),
328-
// }
329-
// }
330-
// }
331-
332-
// impl Arbitrary for TcpMatch {
333-
// fn arbitrary<G: Gen>(g: &mut G) -> Self {
334-
// if g.gen::<bool>() {
335-
// TcpMatch::Net(NetMatch::arbitrary(g))
336-
// } else {
337-
// TcpMatch::PortRange(g.gen(), g.gen())
338-
// }
339-
// }
340-
// }
341-
342-
// impl Arbitrary for NetMatch {
343-
// fn arbitrary<G: Gen>(g: &mut G) -> Self {
344-
// if g.gen::<bool>() {
345-
// let addr = net::Ipv4Addr::arbitrary(g);
346-
// let bits = g.gen::<u8>() % 32;
347-
// let net = Ipv4Net::new(addr, bits).expect("ipv4 network address");
348-
// NetMatch::Net4(net)
349-
// } else {
350-
// let addr = net::Ipv6Addr::arbitrary(g);
351-
// let bits = g.gen::<u8>() % 128;
352-
// let net = Ipv6Net::new(addr, bits).expect("ipv6 network address");
353-
// NetMatch::Net6(net)
354-
// }
355-
// }
356-
// }
357-
358-
// quickcheck! {
359-
// fn tcp_from_proto(tcp: observe_request::r#match::Tcp) -> bool {
360-
// use self::observe_request::r#match::tcp;
361-
362-
// let err: Option<InvalidMatch> =
363-
// tcp.r#match.as_ref()
364-
// .map(|m| match m {
365-
// tcp::Match::Ports(ps) => {
366-
// let ok = 0 < ps.min &&
367-
// ps.min <= ps.max &&
368-
// ps.max < u32::from(::std::u16::MAX);
369-
// if ok { None } else { Some(InvalidMatch::InvalidPort) }
370-
// }
371-
// tcp::Match::Netmask(n) => {
372-
// match n.ip.as_ref().and_then(|ip| ip.ip.as_ref()) {
373-
// Some(_) => None,
374-
// None => Some(InvalidMatch::Empty),
375-
// }
376-
// }
377-
// })
378-
// .unwrap_or(Some(InvalidMatch::Empty));
379-
380-
// err == TcpMatch::try_from(tcp).err()
381-
// }
382-
383-
// fn tcp_matches(m: TcpMatch, addr: net::SocketAddr) -> bool {
384-
// let matches = match (&m, addr.ip()) {
385-
// (&TcpMatch::Net(NetMatch::Net4(ref n)), net::IpAddr::V4(ip)) => {
386-
// n.contains(&ip)
387-
// }
388-
// (&TcpMatch::Net(NetMatch::Net6(ref n)), net::IpAddr::V6(ip)) => {
389-
// n.contains(&ip)
390-
// }
391-
// (&TcpMatch::PortRange(min, max), _) => {
392-
// min <= addr.port() && addr.port() <= max
393-
// }
394-
// _ => false
395-
// };
396-
397-
// m.matches(addr) == matches
398-
// }
399-
400-
// fn labels_from_proto(label: observe_request::r#match::Label) -> bool {
401-
// let err: Option<InvalidMatch> =
402-
// if label.key.is_empty() || label.value.is_empty() {
403-
// Some(InvalidMatch::Empty)
404-
// } else {
405-
// None
406-
// };
407-
408-
// err == LabelMatch::try_from(label).err()
409-
// }
410-
411-
// fn label_matches(l: LabelMatch, labels: HashMap<String, String>) -> bool {
412-
// use std::iter::FromIterator;
413-
414-
// let matches = labels.get(&l.key) == Some(&l.value);
415-
// l.matches(&IndexMap::from_iter(labels.into_iter())) == matches
416-
// }
417-
418-
// fn http_from_proto(http: observe_request::r#match::Http) -> bool {
419-
// use self::observe_request::r#match::http;
420-
421-
// let err = match http.r#match.as_ref() {
422-
// None => Some(InvalidMatch::Empty),
423-
// Some(http::Match::Method(ref m)) => {
424-
// match m.r#type.as_ref() {
425-
// None => Some(InvalidMatch::Empty),
426-
// Some(http_types::http_method::Type::Unregistered(ref m)) if m.len() > 15 => {
427-
// Some(InvalidMatch::InvalidHttpMethod)
428-
// }
429-
// Some(http_types::http_method::Type::Unregistered(m)) => {
430-
// ::http::Method::from_bytes(m.as_bytes())
431-
// .err()
432-
// .map(|_| InvalidMatch::InvalidHttpMethod)
433-
// }
434-
// Some(http_types::http_method::Type::Registered(m)) if *m >= 9 => {
435-
// Some(InvalidMatch::InvalidHttpMethod)
436-
// }
437-
// Some(http_types::http_method::Type::Registered(_)) => None,
438-
// }
439-
// }
440-
// Some(http::Match::Scheme(m)) => match m.r#type.as_ref() {
441-
// None => Some(InvalidMatch::Empty),
442-
// Some(http_types::scheme::Type::Unregistered(_)) => None,
443-
// Some(http_types::scheme::Type::Registered(m)) if *m < 2 => None,
444-
// Some(http_types::scheme::Type::Registered(_)) => Some(InvalidMatch::InvalidScheme),
445-
// }
446-
// Some(http::Match::Authority(m)) => match m.r#match.as_ref() {
447-
// None => Some(InvalidMatch::Empty),
448-
// Some(_) => None,
449-
// }
450-
// Some(http::Match::Path(m)) => match m.r#match.as_ref() {
451-
// None => Some(InvalidMatch::Empty),
452-
// Some(_) => None,
453-
// }
454-
// };
455-
456-
// err == HttpMatch::try_from(http).err()
457-
// }
458-
// }
459-
// }
313+
#[cfg(test)]
314+
mod tests {
315+
use super::*;
316+
use ipnet::{Ipv4Net, Ipv6Net};
317+
use linkerd2_proxy_api::http_types;
318+
use quickcheck::*;
319+
use std::collections::HashMap;
320+
321+
impl Arbitrary for LabelMatch {
322+
fn arbitrary(gen: &mut Gen) -> Self {
323+
Self {
324+
key: Arbitrary::arbitrary(gen),
325+
value: Arbitrary::arbitrary(gen),
326+
}
327+
}
328+
}
329+
330+
impl Arbitrary for TcpMatch {
331+
fn arbitrary(gen: &mut Gen) -> Self {
332+
if bool::arbitrary(gen) {
333+
TcpMatch::Net(NetMatch::arbitrary(gen))
334+
} else {
335+
TcpMatch::PortRange(u16::arbitrary(gen), u16::arbitrary(gen))
336+
}
337+
}
338+
}
339+
340+
impl Arbitrary for NetMatch {
341+
fn arbitrary(gen: &mut Gen) -> Self {
342+
if bool::arbitrary(gen) {
343+
let addr = net::Ipv4Addr::arbitrary(gen);
344+
let bits = u8::arbitrary(gen) % 32;
345+
let net = Ipv4Net::new(addr, bits).expect("ipv4 network address");
346+
NetMatch::Net4(net)
347+
} else {
348+
let addr = net::Ipv6Addr::arbitrary(gen);
349+
let bits = u8::arbitrary(gen) % 128;
350+
let net = Ipv6Net::new(addr, bits).expect("ipv6 network address");
351+
NetMatch::Net6(net)
352+
}
353+
}
354+
}
355+
356+
quickcheck! {
357+
fn tcp_from_proto(tcp: observe_request::r#match::Tcp) -> bool {
358+
use self::observe_request::r#match::tcp;
359+
360+
let err: Option<InvalidMatch> =
361+
tcp.r#match.as_ref()
362+
.map(|m| match m {
363+
tcp::Match::Ports(ps) => {
364+
let ok = 0 < ps.min &&
365+
ps.min <= ps.max &&
366+
ps.max < u32::from(::std::u16::MAX);
367+
if ok { None } else { Some(InvalidMatch::InvalidPort) }
368+
}
369+
tcp::Match::Netmask(n) => {
370+
match n.ip.as_ref().and_then(|ip| ip.ip.as_ref()) {
371+
Some(_) => None,
372+
None => Some(InvalidMatch::Empty),
373+
}
374+
}
375+
})
376+
.unwrap_or(Some(InvalidMatch::Empty));
377+
378+
err == TcpMatch::try_from(tcp).err()
379+
}
380+
381+
fn tcp_matches(m: TcpMatch, addr: net::SocketAddr) -> bool {
382+
let matches = match (&m, addr.ip()) {
383+
(&TcpMatch::Net(NetMatch::Net4(ref n)), net::IpAddr::V4(ip)) => {
384+
n.contains(&ip)
385+
}
386+
(&TcpMatch::Net(NetMatch::Net6(ref n)), net::IpAddr::V6(ip)) => {
387+
n.contains(&ip)
388+
}
389+
(&TcpMatch::PortRange(min, max), _) => {
390+
min <= addr.port() && addr.port() <= max
391+
}
392+
_ => false
393+
};
394+
395+
m.matches(addr) == matches
396+
}
397+
398+
fn labels_from_proto(label: observe_request::r#match::Label) -> bool {
399+
let err: Option<InvalidMatch> =
400+
if label.key.is_empty() || label.value.is_empty() {
401+
Some(InvalidMatch::Empty)
402+
} else {
403+
None
404+
};
405+
406+
err == LabelMatch::try_from(label).err()
407+
}
408+
409+
fn label_matches(l: LabelMatch, labels: HashMap<String, String>) -> bool {
410+
let matches = labels.get(&l.key) == Some(&l.value);
411+
l.matches(&labels.into_iter().collect()) == matches
412+
}
413+
414+
fn http_from_proto(http: observe_request::r#match::Http) -> bool {
415+
use self::observe_request::r#match::http;
416+
417+
let err = match http.r#match.as_ref() {
418+
None => Some(InvalidMatch::Empty),
419+
Some(http::Match::Method(ref m)) => {
420+
match m.r#type.as_ref() {
421+
None => Some(InvalidMatch::Empty),
422+
Some(http_types::http_method::Type::Unregistered(ref m)) if m.len() > 15 => {
423+
Some(InvalidMatch::InvalidHttpMethod)
424+
}
425+
Some(http_types::http_method::Type::Unregistered(m)) => {
426+
::http::Method::from_bytes(m.as_bytes())
427+
.err()
428+
.map(|_| InvalidMatch::InvalidHttpMethod)
429+
}
430+
Some(http_types::http_method::Type::Registered(m)) if *m >= 9 => {
431+
Some(InvalidMatch::InvalidHttpMethod)
432+
}
433+
Some(http_types::http_method::Type::Registered(_)) => None,
434+
}
435+
}
436+
Some(http::Match::Scheme(m)) => match m.r#type.as_ref() {
437+
None => Some(InvalidMatch::Empty),
438+
Some(http_types::scheme::Type::Unregistered(_)) => None,
439+
Some(http_types::scheme::Type::Registered(m)) if *m < 2 => None,
440+
Some(http_types::scheme::Type::Registered(_)) => Some(InvalidMatch::InvalidScheme),
441+
}
442+
Some(http::Match::Authority(m)) => match m.r#match.as_ref() {
443+
None => Some(InvalidMatch::Empty),
444+
Some(_) => None,
445+
}
446+
Some(http::Match::Path(m)) => match m.r#match.as_ref() {
447+
None => Some(InvalidMatch::Empty),
448+
Some(_) => None,
449+
}
450+
};
451+
452+
err == HttpMatch::try_from(http).err()
453+
}
454+
}
455+
}

0 commit comments

Comments
 (0)