1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use async_utils::PollExt;
6use fuchsia_async as fasync;
7use futures::future::Either;
8use futures::stream::{Stream, StreamExt};
9use futures::task::Poll;
10use futures::Future;
11use std::pin::pin;
1213///! Utilities for tests
1415/// Run a background task while waiting for a future that should occur.
16/// This is useful for running a task which you expect to produce side effects that
17/// mean the task is operating correctly. i.e. reacting to a peer action by producing a
18/// response on a client's hanging get.
19/// `background_fut` is expected not to finish ans is returned to the caller, along with
20/// the result of `result_fut`. If `background_fut` finishes, this function will panic.
21pub fn run_while<BackgroundFut, ResultFut, Out>(
22 exec: &mut fasync::TestExecutor,
23 background_fut: BackgroundFut,
24 result_fut: ResultFut,
25) -> (Out, BackgroundFut)
26where
27BackgroundFut: Future + Unpin,
28 ResultFut: Future<Output = Out>,
29{
30let result_fut = pin!(result_fut);
31let mut select_fut = futures::future::select(background_fut, result_fut);
32loop {
33match exec.run_until_stalled(&mut select_fut) {
34 Poll::Ready(Either::Right(r)) => return r,
35 Poll::Ready(Either::Left(_)) => panic!("Background future finished"),
36 Poll::Pending => {}
37 }
38 }
39}
4041/// Polls the provided `stream` and expects a non-null item to be produced.
42#[track_caller]
43pub fn expect_stream_item<S: Stream + Unpin>(
44 exec: &mut fasync::TestExecutor,
45 stream: &mut S,
46) -> S::Item {
47 exec.run_until_stalled(&mut stream.next()).expect("stream item").expect("not terminated")
48}
4950/// Polls the provided `stream` and expects that it is Pending (e.g no stream items).
51#[track_caller]
52pub fn expect_stream_pending<S: Stream + Unpin>(exec: &mut fasync::TestExecutor, stream: &mut S) {
53let _ = exec.run_until_stalled(&mut stream.next()).expect_pending("stream pending");
54}
5556/// Polls the provided `stream` and expects that it is terminated (e.g. returns None).
57#[track_caller]
58pub fn expect_stream_terminated<S: Stream + Unpin>(
59 exec: &mut fasync::TestExecutor,
60 stream: &mut S,
61) {
62let result = exec.run_until_stalled(&mut stream.next()).expect("stream item");
63assert!(result.is_none());
64}