Repository: fujiapple852/trippy
Pull request #1386 (2024-11-23 12:06:40)

Test improve state tests


Patch:
diff --git a/crates/trippy-core/src/state.rs b/crates/trippy-core/src/state.rs
index a11e6f2..9581770 100644
--- a/crates/trippy-core/src/state.rs
+++ b/crates/trippy-core/src/state.rs
@@ -665,6 +665,7 @@ mod tests {
     use anyhow::anyhow;
     use serde::Deserialize;
     use std::collections::HashSet;
+    use std::fmt::Debug;
     use std::ops::Add;
     use std::str::FromStr;
     use std::time::SystemTime;
@@ -790,24 +791,24 @@ mod tests {
     #[derive(Deserialize, Debug, Clone)]
     #[serde(deny_unknown_fields)]
     struct HopData {
-        ttl: u8,
-        total_sent: usize,
-        total_recv: usize,
-        loss_pct: f64,
+        ttl: Option<u8>,
+        total_sent: Option<usize>,
+        total_recv: Option<usize>,
+        loss_pct: Option<f64>,
         last_ms: Option<f64>,
         best_ms: Option<f64>,
         worst_ms: Option<f64>,
-        avg_ms: f64,
+        avg_ms: Option<f64>,
         jitter: Option<f64>,
-        javg: f64,
+        javg: Option<f64>,
         jmax: Option<f64>,
-        jinta: f64,
-        addrs: HashMap<IpAddr, usize>,
+        jinta: Option<f64>,
+        addrs: Option<HashMap<IpAddr, usize>>,
         samples: Option<Vec<f64>>,
-        last_src: u16,
-        last_dest: u16,
-        last_sequence: u16,
-        last_nat_status: NatStatusWrapper,
+        last_src: Option<u16>,
+        last_dest: Option<u16>,
+        last_sequence: Option<u16>,
+        last_nat_status: Option<NatStatusWrapper>,
     }
 
     /// A wrapper struct over `NatStatus` to allow deserialization.
@@ -830,16 +831,17 @@ mod tests {
 
     macro_rules! file {
         ($path:expr) => {{
-            let yaml = include_str!(concat!("../tests/resources/backend/", $path));
+            let yaml = include_str!(concat!("../tests/resources/state/", $path));
             serde_yml::from_str(yaml).unwrap()
         }};
     }
 
-    #[test_case(file!("ipv4_3probes_3hops_mixed_multi.yaml"))]
-    #[test_case(file!("ipv4_3probes_3hops_completed.yaml"))]
-    #[test_case(file!("ipv4_4probes_all_status.yaml"))]
-    #[test_case(file!("ipv4_4probes_0latency.yaml"))]
-    #[test_case(file!("ipv4_nat.yaml"))]
+    #[test_case(file!("full_mixed.yaml"))]
+    #[test_case(file!("full_completed.yaml"))]
+    #[test_case(file!("all_status.yaml"))]
+    #[test_case(file!("no_latency.yaml"))]
+    #[test_case(file!("nat.yaml"))]
+    #[test_case(file!("minimal.yaml"))]
     fn test_scenario(scenario: Scenario) {
         let mut trace = State::new(StateConfig {
             max_flows: 1,
@@ -859,49 +861,80 @@ mod tests {
         let actual_hops = trace.hops();
         let expected_hops = scenario.expected.hops;
         for (actual, expected) in actual_hops.iter().zip(expected_hops) {
-            assert_eq!(actual.ttl(), expected.ttl);
-            assert_eq!(
-                actual.addrs().collect::<HashSet<_>>(),
-                expected.addrs.keys().collect::<HashSet<_>>()
+            assert_eq_opt(&Some(actual.ttl()), &expected.ttl);
+            assert_eq_opt(
+                &Some(actual.addrs().collect::<HashSet<_>>()),
+                &expected
+                    .addrs
+                    .as_ref()
+                    .map(|addrs| addrs.keys().collect::<HashSet<_>>()),
             );
-            assert_eq!(actual.addr_count(), expected.addrs.len());
-            assert_eq!(actual.total_sent(), expected.total_sent);
-            assert_eq!(actual.total_recv(), expected.total_recv);
-            assert_eq_optional(Some(actual.loss_pct()), Some(expected.loss_pct));
-            assert_eq_optional(actual.last_ms(), expected.last_ms);
-            assert_eq_optional(actual.best_ms(), expected.best_ms);
-            assert_eq_optional(actual.worst_ms(), expected.worst_ms);
-            assert_eq_optional(Some(actual.avg_ms()), Some(expected.avg_ms));
-            assert_eq_optional(actual.jitter_ms(), expected.jitter);
-            assert_eq_optional(Some(actual.javg_ms()), Some(expected.javg));
-            assert_eq_optional(actual.jmax_ms(), expected.jmax);
-            assert_eq_optional(Some(actual.jinta()), Some(expected.jinta));
-            assert_eq!(actual.last_src_port(), expected.last_src);
-            assert_eq!(actual.last_dest_port(), expected.last_dest);
-            assert_eq!(actual.last_sequence(), expected.last_sequence);
-            assert_eq!(actual.last_nat_status(), expected.last_nat_status.0);
-            assert_eq!(
-                Some(
+            assert_eq_opt(
+                &Some(actual.addr_count()),
+                &expected.addrs.map(|addrs| addrs.len()),
+            );
+            assert_eq_opt(&Some(actual.total_sent()), &expected.total_sent);
+            assert_eq_opt(&Some(actual.total_recv()), &expected.total_recv);
+            assert_eq_opt_f64(&Some(actual.loss_pct()), &expected.loss_pct);
+            assert_eq_opt_f64(&actual.last_ms(), &expected.last_ms);
+            assert_eq_opt_f64(&actual.best_ms(), &expected.best_ms);
+            assert_eq_opt_f64(&actual.worst_ms(), &expected.worst_ms);
+            assert_eq_opt_f64(&Some(actual.avg_ms()), &expected.avg_ms);
+            assert_eq_opt_f64(&actual.jitter_ms(), &expected.jitter);
+            assert_eq_opt_f64(&Some(actual.javg_ms()), &expected.javg);
+            assert_eq_opt_f64(&actual.jmax_ms(), &expected.jmax);
+            assert_eq_opt_f64(&Some(actual.jinta()), &expected.jinta);
+            assert_eq_opt(&Some(actual.last_src_port()), &expected.last_src);
+            assert_eq_opt(&Some(actual.last_dest_port()), &expected.last_dest);
+            assert_eq_opt(&Some(actual.last_sequence()), &expected.last_sequence);
+            assert_eq_opt(
+                &Some(actual.last_nat_status()),
+                &expected.last_nat_status.map(|nat| nat.0),
+            );
+            assert_eq_vec_f64(
+                &Some(
                     actual
                         .samples()
                         .iter()
                         .map(|s| s.as_secs_f64() * 1000_f64)
-                        .collect()
+                        .collect(),
                 ),
-                expected.samples
+                &expected.samples,
             );
         }
     }
 
-    fn assert_eq_optional(actual: Option<f64>, expected: Option<f64>) {
+    fn assert_eq_opt<T: Eq + Debug>(actual: &Option<T>, expected: &Option<T>) {
+        assert_eq_inner(actual, expected, |a, e| a == e);
+    }
+
+    fn assert_eq_opt_f64(actual: &Option<f64>, expected: &Option<f64>) {
+        assert_eq_inner(actual, expected, |a, e| (e - a).abs() < f64::EPSILON);
+    }
+
+    fn assert_eq_vec_f64(actual: &Option<Vec<f64>>, expected: &Option<Vec<f64>>) {
+        assert_eq_inner(actual, expected, |a, e| {
+            if a.len() != e.len() {
+                return false;
+            }
+            a.iter()
+                .zip(e.iter())
+                .all(|(a, e)| (e - a).abs() < f64::EPSILON)
+        });
+    }
+
+    fn assert_eq_inner<T: Debug>(
+        actual: &Option<T>,
+        expected: &Option<T>,
+        eq: impl Fn(&T, &T) -> bool,
+    ) {
         match (actual, expected) {
-            (Some(actual), Some(expected)) if (expected - actual).abs() < f64::EPSILON => {}
+            (Some(actual), Some(expected)) if eq(actual, expected) => {}
             (Some(actual), Some(expected)) => {
                 panic!("expected {expected:?} did not match actual {actual:?}")
             }
-            (Some(_), None) => panic!("actual {actual:?} but not expected"),
             (None, Some(_)) => panic!("expected {expected:?} but no actual"),
-            (None, None) => {}
+            (_, None) => {}
         }
     }
 }


Test patch:
diff --git a/crates/trippy-core/tests/resources/backend/ipv4_nat.yaml b/crates/trippy-core/tests/resources/backend/ipv4_nat.yaml
deleted file mode 100644
index 8f1d80f..0000000
--- a/crates/trippy-core/tests/resources/backend/ipv4_nat.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
-largest_ttl: 3
-rounds:
-  - probes:
-      - 1 C 333 10.1.0.1 0 12340 80 43012 43012
-      - 2 C 777 10.1.0.2 1 12340 80 20544 20544
-      - 3 C 778 10.1.0.3 2 12340 80 20544 20544
-  - probes:
-      - 1 C 123 10.1.0.1 3 12340 80 43012 43012
-      - 2 C 788 10.1.0.2 4 12340 80 20544 20544
-      - 3 C 789 10.1.0.3 5 12340 80 20544 20544
-  - probes:
-      - 1 C 123 10.1.0.1 6 12340 80 43012 43012
-      - 2 C 780 10.1.0.2 7 12340 80 20544 20544
-      - 3 C 781 10.1.0.3 8 12340 80 20544 20544
-expected:
-  hops:
-    - ttl: 1
-      total_sent: 3
-      total_recv: 3
-      loss_pct: 0
-      best_ms: 123
-      worst_ms: 333
-      avg_ms: 193
-      jitter: 0
-      javg: 181.0
-      jinta: 488.642578125
-      jmax: 333
-      last_nat_status: no_nat
-      addrs:
-        10.1.0.1: 3
-      samples: [123, 123, 333]
-      last_ms: 123
-      last_sequence: 6
-      last_src: 12340
-      last_dest: 80
-    - ttl: 2
-      total_sent: 3
-      total_recv: 3
-      loss_pct: 0
-      best_ms: 777
-      worst_ms: 788
-      avg_ms: 781.6666666666665
-      jitter: 8
-      javg: 265.33333333333337
-      jinta: 699.814453125
-      jmax: 777.0
-      last_nat_status: nat
-      addrs:
-        10.1.0.2: 3
-      samples: [780, 788, 777]
-      last_ms: 780
-      last_sequence: 7
-      last_src: 12340
-      last_dest: 80
-    - ttl: 3
-      total_sent: 3
-      total_recv: 3
-      loss_pct: 0
-      best_ms: 778
-      worst_ms: 789
-      avg_ms: 782.6666666666666
-      jitter: 8
-      javg: 265.66666666666663
-      jinta: 700.693359375
-      jmax: 778.0
-      last_nat_status: no_nat
-      addrs:
-        10.1.0.3: 3
-      samples: [781, 789, 778]
-      last_ms: 781
-      last_sequence: 8
-      last_src: 12340
-      last_dest: 80
diff --git a/crates/trippy-core/tests/resources/backend/ipv4_4probes_all_status.yaml b/crates/trippy-core/tests/resources/state/all_status.yaml
similarity index 80%
rename from crates/trippy-core/tests/resources/backend/ipv4_4probes_all_status.yaml
rename to crates/trippy-core/tests/resources/state/all_status.yaml
index 4cb78dd..d614068 100644
--- a/crates/trippy-core/tests/resources/backend/ipv4_4probes_all_status.yaml
+++ b/crates/trippy-core/tests/resources/state/all_status.yaml
@@ -17,15 +17,10 @@ expected:
       best_ms: 700
       worst_ms: 700
       avg_ms: 700
-      # jitter: None
-      javg: 700
-      jmax: 700
-      jinta: 699.5
-      last_nat_status: no_nat
       addrs:
         10.1.0.2: 1
       samples: [700.0, 0.0]
       last_ms: 700
       last_sequence: 0
       last_src: 12340
-      last_dest: 80 
+      last_dest: 80
\ No newline at end of file
diff --git a/crates/trippy-core/tests/resources/backend/ipv4_3probes_3hops_completed.yaml b/crates/trippy-core/tests/resources/state/full_completed.yaml
similarity index 100%
rename from crates/trippy-core/tests/resources/backend/ipv4_3probes_3hops_completed.yaml
rename to crates/trippy-core/tests/resources/state/full_completed.yaml
diff --git a/crates/trippy-core/tests/resources/backend/ipv4_3probes_3hops_mixed_multi.yaml b/crates/trippy-core/tests/resources/state/full_mixed.yaml
similarity index 100%
rename from crates/trippy-core/tests/resources/backend/ipv4_3probes_3hops_mixed_multi.yaml
rename to crates/trippy-core/tests/resources/state/full_mixed.yaml
diff --git a/crates/trippy-core/tests/resources/state/minimal.yaml b/crates/trippy-core/tests/resources/state/minimal.yaml
new file mode 100644
index 0000000..e379803
--- /dev/null
+++ b/crates/trippy-core/tests/resources/state/minimal.yaml
@@ -0,0 +1,11 @@
+largest_ttl: 3
+rounds:
+  - probes:
+      - 1 C 333 10.1.0.1 0 12340 80 0 0
+      - 2 C 777 10.1.0.2 1 12340 80 0 0
+      - 3 C 778 10.1.0.3 2 12340 80 0 0
+expected:
+  hops:
+    - ttl: 1
+    - ttl: 2
+    - ttl: 3
\ No newline at end of file
diff --git a/crates/trippy-core/tests/resources/state/nat.yaml b/crates/trippy-core/tests/resources/state/nat.yaml
new file mode 100644
index 0000000..197fb17
--- /dev/null
+++ b/crates/trippy-core/tests/resources/state/nat.yaml
@@ -0,0 +1,22 @@
+largest_ttl: 3
+rounds:
+  - probes:
+      - 1 C 333 10.1.0.1 0 12340 80 43012 43012
+      - 2 C 777 10.1.0.2 1 12340 80 20544 20544
+      - 3 C 778 10.1.0.3 2 12340 80 20544 20544
+  - probes:
+      - 1 C 123 10.1.0.1 3 12340 80 43012 43012
+      - 2 C 788 10.1.0.2 4 12340 80 20544 20544
+      - 3 C 789 10.1.0.3 5 12340 80 20544 20544
+  - probes:
+      - 1 C 123 10.1.0.1 6 12340 80 43012 43012
+      - 2 C 780 10.1.0.2 7 12340 80 20544 20544
+      - 3 C 781 10.1.0.3 8 12340 80 20544 20544
+expected:
+  hops:
+    - ttl: 1
+      last_nat_status: no_nat
+    - ttl: 2
+      last_nat_status: nat
+    - ttl: 3
+      last_nat_status: no_nat
\ No newline at end of file
diff --git a/crates/trippy-core/tests/resources/backend/ipv4_4probes_0latency.yaml b/crates/trippy-core/tests/resources/state/no_latency.yaml
similarity index 69%
rename from crates/trippy-core/tests/resources/backend/ipv4_4probes_0latency.yaml
rename to crates/trippy-core/tests/resources/state/no_latency.yaml
index 8f4f0ff..34ab807 100644
--- a/crates/trippy-core/tests/resources/backend/ipv4_4probes_0latency.yaml
+++ b/crates/trippy-core/tests/resources/state/no_latency.yaml
@@ -11,21 +11,13 @@ rounds:
 expected:
   hops:
     - ttl: 1
-      total_sent: 4
-      total_recv: 4
       loss_pct: 0
       last_ms: 0.0
       best_ms: 0
       worst_ms: 0
       avg_ms: 0
-      last_nat_status: no_nat
-      addrs:
-        127.0.0.1: 1
       samples: [0, 0, 0, 0]
       jitter: 0
       javg: 0.0
       jmax: 0.0
-      jinta: 0.0
-      last_sequence: 0
-      last_src: 80
-      last_dest: 80
+      jinta: 0.0
\ No newline at end of file