Repository: tokio-rs/tokio
File: tokio/tests/rt_unstable_metrics.rs (Rust)

Code before:

    let mut successfully_spawned_stealable_task = false;

    rt.block_on(async {
        for _ in 0..10 {
            // The call to `try_spawn_stealable_task` may time out, which means
            // that the sending task couldn't be scheduled due to a deadlock in
            // the runtime.
            // This is expected behaviour, we just retry until we succeed or
            // exhaust all tries, the latter causing this test to fail.
            if try_spawn_stealable_task().await.is_ok() {
                successfully_spawned_stealable_task = true;
                break;
            }
        }
    });

    drop(rt);

    if !successfully_spawned_stealable_task {
        panic!("exhausted every try to schedule the stealable task");
    }

    let n: u64 = (0..metrics.num_workers())
        .map(|i| metrics.worker_steal_count(i))
        .sum();

    assert_eq!(1, n);
}

#[test]
fn worker_poll_count_and_time() {
    const N: u64 = 5;

    async fn task() {
        // Sync sleep
        std::thread::sleep(std::time::Duration::from_micros(10));
    }

    let rt = current_thread();
    let metrics = rt.metrics();
    rt.block_on(async {
        for _ in 0..N {
            tokio::spawn(task()).await.unwrap();
        }
    });
    drop(rt);
    assert_eq!(N, metrics.worker_poll_count(0));
    // Not currently supported for current-thread runtime
    assert_eq!(Duration::default(), metrics.worker_mean_poll_time(0));


Review comment (bug):
We should recreate the runtime on failure. Otherwise a failed round could result in this number being wrong.

Code after:

        let successfully_spawned_stealable_task = rt.block_on(async {
            // The call to `try_spawn_stealable_task` may time out, which means
            // that the sending task couldn't be scheduled due to a deadlock in
            // the runtime.
            // This is expected behaviour, we just retry until we succeed or
            // exhaust all tries, the latter causing this test to fail.
            try_spawn_stealable_task().await.is_ok()
        });

        drop(rt);

        if successfully_spawned_stealable_task {
            let n: u64 = (0..metrics.num_workers())
                .map(|i| metrics.worker_steal_count(i))
                .sum();

            assert_eq!(1, n);
            return;
        }
    }

    panic!("exhausted every try to schedule the stealable task");
}

#[test]
fn worker_poll_count_and_time() {
    const N: u64 = 5;

    async fn task() {
        // Sync sleep
        std::thread::sleep(std::time::Duration::from_micros(10));
    }

    let rt = current_thread();
    let metrics = rt.metrics();
    rt.block_on(async {
        for _ in 0..N {
            tokio::spawn(task()).await.unwrap();
        }
    });
    drop(rt);
    assert_eq!(N, metrics.worker_poll_count(0));
    // Not currently supported for current-thread runtime
    assert_eq!(Duration::default(), metrics.worker_mean_poll_time(0));

    // Does not populate the histogram
    assert!(!metrics.poll_time_histogram_enabled());
    for i in 0..10 {
        assert_eq!(0, metrics.poll_time_histogram_bucket_count(0, i));
    }