Commit 99a046da authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Get tor-units grcov line coverage to 100%

This is mostly a finger exercise, and an experiment in "what does
grcov consider to be coverage".  Here's what I've found out...

* In grcov's eyes, most #[derive(Foo)] lines count as containing code;
  but calling any one derived function counts as calling those lines.

* Unlike with tarpaulin, it is actually possible to reach 100% grcov
  line coverage.  (Tarpaulin likes to pick "}" lines and tell you that
  you never reached them; or sometimes it picks expression
  statements that have the effect of a return, and tells you that
  they're unreached.  Even with these tests, tarpaulin claims that
  the line coverage of tor-units is only 97.3%.)

* In rust, it may be a bit hopeless trying to get high function
  coverage. Even though we've hit every line of the tor-units crate,
  the function coverage from its own tests is only 9.38% (55.41%
  from other crates).  I think this is probably due to derived
  functions, or maybe due to generics getting instantiated?
  I've got no idea; the denominator for the function coverage
  lines fluctuates oddly.
parent 47614ee7
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -557,6 +557,16 @@ mod tests {
        assert_eq!(d, 255);
    }

    #[test]
    fn try_into_usize() {
        let b0: BoundedInt32<-10, 300> = BoundedInt32::saturating_from(0);
        let b100: BoundedInt32<-10, 300> = BoundedInt32::saturating_from(100);
        let bn5: BoundedInt32<-10, 300> = BoundedInt32::saturating_from(-5);
        assert_eq!(usize::try_from(b0), Ok(0_usize));
        assert_eq!(usize::try_from(b100), Ok(100_usize));
        assert_eq!(usize::try_from(bn5), Err(Error::Negative));
    }

    #[test]
    fn percents() {
        type Pct = Percentage<u8>;
@@ -570,7 +580,11 @@ mod tests {

        let p = Pct::new(25);
        assert_eq!(p.as_percent(), 25);
        assert_eq!(p.clone(), p);
        assert_approx_eq!(f64, p.as_fraction(), 0.25);

        type BPct = Percentage<BoundedInt32<0, 100>>;
        assert_eq!(BPct::try_from(99).unwrap().as_percent().get(), 99);
    }

    #[test]
@@ -580,10 +594,19 @@ mod tests {
        let ms = Msec::new(500);
        let d: Result<Duration, _> = ms.try_into();
        assert_eq!(d.unwrap(), Duration::from_millis(500));
        assert_eq!(Duration::try_from(ms * 2).unwrap(), Duration::from_secs(1));

        let ms = Msec::new(-100);
        let d: Result<Duration, _> = ms.try_into();
        assert!(d.is_err());

        type BMSec = IntegerMilliseconds<BoundedInt32<0, 1000>>;
        let half_sec = BMSec::try_from(500).unwrap();
        assert_eq!(
            Duration::try_from(half_sec).unwrap(),
            Duration::from_millis(500)
        );
        assert!(BMSec::try_from(1001).is_err());
    }

    #[test]
@@ -597,6 +620,15 @@ mod tests {
        let ms = Sec::new(-100);
        let d: Result<Duration, _> = ms.try_into();
        assert!(d.is_err());

        type BSec = IntegerSeconds<BoundedInt32<0, 3600>>;
        let half_hour = BSec::try_from(1800).unwrap();
        assert_eq!(
            Duration::try_from(half_hour).unwrap(),
            Duration::from_secs(1800)
        );
        assert!(BSec::try_from(9999).is_err());
        assert_eq!(half_hour.clone(), half_hour);
    }

    #[test]
@@ -614,11 +646,19 @@ mod tests {
        let t = IntegerDays::<u64>::new(u64::MAX);
        let d: Result<Duration, _> = t.try_into();
        assert_eq!(d, Err(Error::Overflow));

        type BDays = IntegerDays<BoundedInt32<10, 30>>;
        assert_eq!(
            BDays::new(17_i32.try_into().unwrap()),
            BDays::try_from(17).unwrap()
        );
    }

    #[test]
    fn sendme() {
        let smv = SendMeVersion::new(5);
        assert_eq!(smv.get(), 5);
        assert_eq!(smv.clone().get(), 5);
        assert_eq!(smv, SendMeVersion::try_from(5).unwrap());
    }
}