Skip to main content

xwt_tests/tests/
uni_streams.rs

1//! This test exercises the unidirectional streams in both directions:
2//! the client opens a unidirectional stream and finishes it, and then accepts
3//! a unidirectional stream that the server opens to send the data back.
4
5use xwt_core::prelude::*;
6
7#[derive(Debug, thiserror::Error)]
8pub enum Error<Endpoint>
9where
10    Endpoint: xwt_core::endpoint::Connect + std::fmt::Debug,
11    Endpoint::Connecting: std::fmt::Debug,
12    ConnectSessionFor<Endpoint>:
13        xwt_core::session::stream::OpenUni + xwt_core::session::stream::AcceptUni + std::fmt::Debug,
14{
15    #[error("connect: {0}")]
16    Connect(#[source] xwt_error::Connect<Endpoint>),
17    #[error("open: {0}")]
18    Open(#[source] xwt_error::OpenUni<ConnectSessionFor<Endpoint>>),
19    #[error("send: {0}")]
20    Send(#[source] WriteErrorFor<SendStreamFor<ConnectSessionFor<Endpoint>>>),
21    #[error("finish: {0}")]
22    Finish(#[source] FinishErrorFor<SendStreamFor<ConnectSessionFor<Endpoint>>>),
23    #[error("accept uni stream: {0}")]
24    AcceptUniStream(#[source] UniStreamAcceptErrorFor<ConnectSessionFor<Endpoint>>),
25    #[error("recv: {0}")]
26    Recv(#[source] ReadErrorFor<RecvStreamFor<ConnectSessionFor<Endpoint>>>),
27    #[error("bad data")]
28    BadData(Vec<u8>),
29}
30
31pub async fn run<Endpoint>(endpoint: Endpoint, url: &str) -> Result<(), Error<Endpoint>>
32where
33    Endpoint: xwt_core::endpoint::Connect + std::fmt::Debug,
34    Endpoint::Connecting: std::fmt::Debug,
35    ConnectSessionFor<Endpoint>:
36        xwt_core::session::stream::OpenUni + xwt_core::session::stream::AcceptUni + std::fmt::Debug,
37{
38    let session = crate::utils::connect(&endpoint, url)
39        .await
40        .map_err(Error::Connect)?;
41
42    let mut send_stream = crate::utils::open_uni(&session)
43        .await
44        .map_err(Error::Open)?;
45
46    let mut to_write = &b"hello"[..];
47    loop {
48        let written = send_stream.write(to_write).await.map_err(Error::Send)?;
49        let written = written.get();
50        to_write = &to_write[written..];
51        if to_write.is_empty() {
52            break;
53        }
54    }
55
56    // The server only responds once it has read our stream to the end, so
57    // the stream has to be finished for the test to make progress.
58    send_stream.finish().await.map_err(Error::Finish)?;
59
60    let mut recv_stream = session.accept_uni().await.map_err(Error::AcceptUniStream)?;
61
62    let mut read_buf = vec![0u8; 1024];
63
64    let read = recv_stream
65        .read(&mut read_buf[..])
66        .await
67        .map_err(Error::Recv)?;
68    let read = read.get();
69    read_buf.truncate(read);
70
71    if read_buf != b"hello" {
72        return Err(Error::BadData(read_buf));
73    }
74
75    Ok(())
76}