Skip to content

Commit

Permalink
Improve test coverage (#65)
Browse files Browse the repository at this point in the history
* Enable logs in tests
* Add tests for error_collector
* Switch to codecov.io
* Move tests to separate files, to ignore them in coverage
* Update coverage badge
  • Loading branch information
Finomnis authored Oct 20, 2023
1 parent 926d497 commit 992ce4a
Show file tree
Hide file tree
Showing 16 changed files with 591 additions and 533 deletions.
18 changes: 7 additions & 11 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ concurrency:
group: coverage-${{ github.ref }}
cancel-in-progress: true
jobs:
coveralls:
name: Coveralls
coverage:
name: Codecov.io
continue-on-error: true
runs-on: ubuntu-latest
env:
Expand All @@ -25,14 +25,10 @@ jobs:
uses: taiki-e/install-action@cargo-llvm-cov
#- uses: Swatinem/rust-cache@v1
- name: Compute Coverage
env:
RUST_LOG: "debug"
run:
cargo llvm-cov
--all-features --workspace
--lcov --output-path lcov.info
- name: Upload to Coveralls
uses: coverallsapp/github-action@master
cargo llvm-cov --all-features --workspace --ignore-filename-regex tests.rs --codecov --output-path codecov.json
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
path-to-lcov: lcov.info
github-token: ${{ secrets.github_token }}
files: codecov.json
fail_ci_if_error: true
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ miette = { version = "5.10.0", features = ["fancy"] }

# Logging
tracing-subscriber = "0.3.17"
tracing-test = "0.2.4"
tracing-test = { version = "0.2.4", features = ["no-env-filter"] }

# Tokio
tokio = { version = "1.32.0", features = ["full"] }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![License](https://img.shields.io/crates/l/tokio-graceful-shutdown)](https://github.com/Finomnis/tokio-graceful-shutdown/blob/main/LICENSE-MIT)
[![Build Status](https://img.shields.io/github/actions/workflow/status/Finomnis/tokio-graceful-shutdown/ci.yml?branch=main)](https://github.com/Finomnis/tokio-graceful-shutdown/actions/workflows/ci.yml?query=branch%3Amain)
[![docs.rs](https://img.shields.io/docsrs/tokio-graceful-shutdown)](https://docs.rs/tokio-graceful-shutdown)
[![Coverage Status](https://img.shields.io/coveralls/github/Finomnis/tokio-graceful-shutdown/main)](https://coveralls.io/github/Finomnis/tokio-graceful-shutdown?branch=main)
[![Coverage Status](https://img.shields.io/codecov/c/github/Finomnis/tokio-graceful-shutdown)](https://app.codecov.io/github/Finomnis/tokio-graceful-shutdown/tree/main)

This crate provides utility functions to perform a graceful shutdown on tokio-rs based services.

Expand Down
12 changes: 0 additions & 12 deletions src/error_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,3 @@ pub enum ErrorAction {
/// Do not forward the error to the parent subsystem.
CatchAndLocalShutdown,
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn derive_traits() {
let x = ErrorAction::CatchAndLocalShutdown;
#[allow(clippy::clone_on_copy)]
let y = x.clone();
assert!(y == x);
}
}
68 changes: 1 addition & 67 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,70 +127,4 @@ impl<ErrType: ErrTypeTraits> SubsystemError<ErrType> {
pub struct CancelledByShutdown;

#[cfg(test)]
mod tests {
use crate::BoxedError;

use super::*;

fn examine_report(report: miette::Report) {
println!("{}", report);
println!("{:?}", report);
// Convert to std::error::Error
let boxed_error: BoxedError = report.into();
println!("{}", boxed_error);
println!("{:?}", boxed_error);
}

#[test]
fn errors_can_be_converted_to_diagnostic() {
examine_report(GracefulShutdownError::ShutdownTimeout::<BoxedError>(Box::new([])).into());
examine_report(GracefulShutdownError::SubsystemsFailed::<BoxedError>(Box::new([])).into());
examine_report(SubsystemJoinError::SubsystemsFailed::<BoxedError>(Arc::new([])).into());
examine_report(SubsystemError::Panicked::<BoxedError>("".into()).into());
examine_report(
SubsystemError::Failed::<BoxedError>("".into(), SubsystemFailure("".into())).into(),
);
examine_report(CancelledByShutdown.into());
}

#[test]
fn extract_related_from_graceful_shutdown_error() {
let related = || {
Box::new([
SubsystemError::Failed("a".into(), SubsystemFailure(String::from("A").into())),
SubsystemError::Panicked("b".into()),
])
};

let matches_related = |data: &[SubsystemError<BoxedError>]| {
let mut iter = data.iter();

let elem = iter.next().unwrap();
assert_eq!(elem.name(), "a");
assert!(matches!(elem, SubsystemError::Failed(_, _)));

let elem = iter.next().unwrap();
assert_eq!(elem.name(), "b");
assert!(matches!(elem, SubsystemError::Panicked(_)));

assert!(iter.next().is_none());
};

matches_related(GracefulShutdownError::ShutdownTimeout(related()).get_subsystem_errors());
matches_related(GracefulShutdownError::SubsystemsFailed(related()).get_subsystem_errors());
matches_related(&GracefulShutdownError::ShutdownTimeout(related()).into_subsystem_errors());
matches_related(
&GracefulShutdownError::SubsystemsFailed(related()).into_subsystem_errors(),
);
}

#[test]
fn extract_contained_error_from_convert_subsystem_failure() {
let msg = "MyFailure".to_string();
let failure = SubsystemFailure(msg.clone());

assert_eq!(&msg, failure.get_error());
assert_eq!(msg, *failure);
assert_eq!(msg, failure.into_error());
}
}
mod tests;
63 changes: 63 additions & 0 deletions src/errors/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::BoxedError;

use super::*;

fn examine_report(report: miette::Report) {
println!("{}", report);
println!("{:?}", report);
// Convert to std::error::Error
let boxed_error: BoxedError = report.into();
println!("{}", boxed_error);
println!("{:?}", boxed_error);
}

#[test]
fn errors_can_be_converted_to_diagnostic() {
examine_report(GracefulShutdownError::ShutdownTimeout::<BoxedError>(Box::new([])).into());
examine_report(GracefulShutdownError::SubsystemsFailed::<BoxedError>(Box::new([])).into());
examine_report(SubsystemJoinError::SubsystemsFailed::<BoxedError>(Arc::new([])).into());
examine_report(SubsystemError::Panicked::<BoxedError>("".into()).into());
examine_report(
SubsystemError::Failed::<BoxedError>("".into(), SubsystemFailure("".into())).into(),
);
examine_report(CancelledByShutdown.into());
}

#[test]
fn extract_related_from_graceful_shutdown_error() {
let related = || {
Box::new([
SubsystemError::Failed("a".into(), SubsystemFailure(String::from("A").into())),
SubsystemError::Panicked("b".into()),
])
};

let matches_related = |data: &[SubsystemError<BoxedError>]| {
let mut iter = data.iter();

let elem = iter.next().unwrap();
assert_eq!(elem.name(), "a");
assert!(matches!(elem, SubsystemError::Failed(_, _)));

let elem = iter.next().unwrap();
assert_eq!(elem.name(), "b");
assert!(matches!(elem, SubsystemError::Panicked(_)));

assert!(iter.next().is_none());
};

matches_related(GracefulShutdownError::ShutdownTimeout(related()).get_subsystem_errors());
matches_related(GracefulShutdownError::SubsystemsFailed(related()).get_subsystem_errors());
matches_related(&GracefulShutdownError::ShutdownTimeout(related()).into_subsystem_errors());
matches_related(&GracefulShutdownError::SubsystemsFailed(related()).into_subsystem_errors());
}

#[test]
fn extract_contained_error_from_convert_subsystem_failure() {
let msg = "MyFailure".to_string();
let failure = SubsystemFailure(msg.clone());

assert_eq!(&msg, failure.get_error());
assert_eq!(msg, *failure);
assert_eq!(msg, failure.into_error());
}
60 changes: 1 addition & 59 deletions src/runner/alive_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,62 +59,4 @@ impl Drop for Inner {
}

#[cfg(test)]
mod tests {

use std::sync::atomic::{AtomicU32, Ordering};

use super::*;

#[test]
fn finished_callback() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);

alive_guard.on_finished(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 1);
}

#[test]
fn cancel_callback() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);

alive_guard.on_finished(|| {});
alive_guard.on_cancel(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 1);
}

#[test]
fn both_callbacks() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);
let counter3 = Arc::clone(&counter);

alive_guard.on_finished(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});
alive_guard.on_cancel(move || {
counter3.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 2);
}
}
mod tests;
69 changes: 69 additions & 0 deletions src/runner/alive_guard/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::sync::atomic::{AtomicU32, Ordering};
use tracing_test::traced_test;

use super::*;

#[test]
#[traced_test]
fn finished_callback() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);

alive_guard.on_finished(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 1);
}

#[test]
#[traced_test]
fn cancel_callback() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);

alive_guard.on_finished(|| {});
alive_guard.on_cancel(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 1);
}

#[test]
#[traced_test]
fn both_callbacks() {
let alive_guard = AliveGuard::new();

let counter = Arc::new(AtomicU32::new(0));
let counter2 = Arc::clone(&counter);
let counter3 = Arc::clone(&counter);

alive_guard.on_finished(move || {
counter2.fetch_add(1, Ordering::Relaxed);
});
alive_guard.on_cancel(move || {
counter3.fetch_add(1, Ordering::Relaxed);
});

drop(alive_guard);

assert_eq!(counter.load(Ordering::Relaxed), 2);
}

#[test]
#[traced_test]
fn no_callback() {
let alive_guard = AliveGuard::new();
drop(alive_guard);

assert!(logs_contain("No `finished` callback was registered in AliveGuard! This should not happen, please report this at https://github.com/Finomnis/tokio-graceful-shutdown/issues."));
}
3 changes: 3 additions & 0 deletions src/subsystem/error_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ impl<ErrType: ErrTypeTraits> Drop for ErrorCollector<ErrType> {
}
}
}

#[cfg(test)]
mod tests;
Loading

0 comments on commit 992ce4a

Please sign in to comment.