Git Product home page Git Product logo

tracing-fluent-assertions's Introduction

tracing-fluent-assertions

A fluent assertions framework for tracing.

overview

While there are already many crates that deal with testing -- mocks, test doubles, advanced assertions, etc -- there aren't any crates that allow a user to understand how their tracing implementation is exercised at a holistic level. While there are some crates, like tracing-test, which exist for figuring out if a chunk of code emitted certain events, there is no generic way to ask questions like:

  • was span A ever created? or entered?
  • did it ever close?
  • did it enter/exit/close at least N times?
  • did any spans in module path X ever get created?

This is the problem that tracing-fluent-assertions aims to solve.

usage

This crate doesn't look terribly dissimilar to other crates which provide fluent assertions, but as it's oriented around spans, which are callsite-defined, there's a little bit of boilerplate involved in using it compared to defining assertions directly against the result of a function, and so on.

Firstly, it provides a Subscriber layer that must be installed so that it can intercept span events and track the lifecycle of spans. Secondly, an AssertionRegistry is provided for creating and storing assertions.

An Assertion defines what spans it should match, and what behavior the spans must match in order to assert successfully.

A condensed usage might look something like this:

use tracing_fluent_assertions::{AssertionLayer, AssertionRegistry};
use tracing_subscriber::{layer::SubscriberExt, Registry};

fn main() {
    // Create the assertion registry and install the assertion layer,
    // then install that subscriber as the global default.
    let assertion_registry = AssertionRegistry::default();
    let base_subscriber = Registry::default();
    let subscriber = base_subscriber.with(AssertionsLayer::new(&assertion_registry));
    tracing::subscriber::set_global_default(subscriber).unwrap();

    // Create an assertion.  We'll look for a span called `shave_yak`,
    // and assert that it's closed at least twice, signalling two full
    // create/enter/exit/closed instances of the span.  Essentially, at
    // least two yaks were completely shaved.
    let more_than_one_shaved_yak = assertion_registry.build()
        .with_name("shave_yak")
        .was_closed_many(2)
        .finalize();

    // Now, call our method that actually shaves the yaks.
    shave_yaks(5);

    // Assuming all five yaks were shaved, this assertion will pass,
    // and no panic will be generated, yay!
    more_than_one_yak_shaved.assert();

    // An advanced usage of assertions can be to figure out when a span
    // has finally been entered.  This can be useful for ascertaining when
    // an asynchronous function has made it through other await points and
    // is now waiting at a piece of code that we control, with its own span.
    //
    // For this, we can use the fallible `try_assert`, which won't panic
    // if the assertion criteria has yet to be entirely met:
    let reached_acquire_shaving_shears = assertion_registry.build()
        .with_name("acquire_shaving_shears")
        .was_entered()
        .finalize();

    let manual_future = shave_yaks_async(5);

    assert!(!reached_acquire_shaving_shears.try_assert());
    while !reached_acquire_shaving_shears.try_assert() {
        manual_future.poll();
    }

    // Once we break out of that loop, we know that we have entered the
    // `acquire_shaving_shears` span at least once.  This example is a bit
    // contrived, but a more useful scenario (albeit with more code required
    // to demonstrate) would be to figure out that one asynchronous task is
    // finally awaiting a specific resource, when it has to await other resources
    // that can't be deterministically controlled when under test.
}

tracing-fluent-assertions's People

Contributors

tobz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.