GithubHelp home page GithubHelp logo

byron / yup-hyper-mock Goto Github PK

View Code? Open in Web Editor NEW
29.0 4.0 14.0 4.72 MB

`hyper-mock` is a utility library to help hyper clients with their testing

Home Page: https://docs.rs/yup-hyper-mock

License: Apache License 2.0

Rust 100.00%

yup-hyper-mock's Introduction

Rust Crates.io

hyper-mock is a utility library to help hyper clients with their testing. It provides types used to test hyper itself, most notably, mock connections and macros to ease their use.

Usage

Set it up for use in tests in Cargo.toml

[dev-dependencies]
yup-hyper-mock = "*"
log = "*"  # log macros are used within yup-hyper-mock

In your tests module

#[cfg(test)]
mod tests {
    use hyper;
    use hyper_util::client::legacy::Client;

    yup_hyper_mock::mock_connector!(MockRedirectPolicy {
        "http://127.0.0.1" =>       "HTTP/1.1 301 Redirect\r\n\
                                     Location: http://127.0.0.2\r\n\
                                     Server: mock1\r\n\
                                     \r\n\
                                    "
        "http://127.0.0.2" =>       "HTTP/1.1 302 Found\r\n\
                                     Location: https://127.0.0.3\r\n\
                                     Server: mock2\r\n\
                                     \r\n\
                                    "
        "https://127.0.0.3" =>      "HTTP/1.1 200 OK\r\n\
                                     Server: mock3\r\n\
                                     \r\n\
                                    "
    });

    #[tokio::test]
    async fn test_redirect_followall() {
        let builder =
            hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new());
        let client: Client<MockRedirectPolicy, http_body_util::Empty<hyper::body::Bytes>> =
            builder.build(MockRedirectPolicy::default());

        let res = client
            .get(hyper::Uri::from_static("http://127.0.0.1"))
            .await
            .unwrap();

        let headers = res.headers();
        assert!(headers.contains_key("Server"));
        assert_eq!(headers["Server"], "mock1");
    }
}

Credits

yup-hyper-mock is code from hyper/src/mock.rs, which was adjusted to work within its very own crate.

License

Licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

yup-hyper-mock's People

Contributors

byron avatar dermesser avatar erichdongubler avatar fussybeaver avatar jessevermeulen123 avatar jwilm avatar notheotherben avatar palfrey avatar rolftimmermans avatar rsolomo avatar ryman avatar talevy avatar thebiggerguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

yup-hyper-mock's Issues

Relicense under dual MIT/Apache-2.0

Why?

The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback, and has protections from
patent trolls and an explicit contribution licensing clause. However, the
Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as
MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and
doing so would be wise for this project. This also makes this crate suitable
for inclusion in the Rust standard distribution and other project using dual
MIT/Apache.

How?

To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright) and then add the following to
your README:

## License

Licensed under either of
 * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you shall be dual licensed as above, without any
additional terms or conditions.

and in your license headers, use the following boilerplate (based on that used in Rust):

// Copyright (c) 2015 t developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

And don't forget to update the license metadata in your Cargo.toml!

Contributor checkoff

Cargo audit advisory: migrate `net2` to `socket2` crate

I get this cargo audit problem when I include yup-hyper-mock:

$ cargo audit --deny warnings
Crate:         net2
Version:       0.2.37
Warning:       unmaintained
Title:         `net2` crate has been deprecated; use `socket2` instead
Date:          2020-05-01
ID:            RUSTSEC-2020-0016
URL:           https://rustsec.org/advisories/RUSTSEC-2020-0016
Dependency tree:
net2 0.2.37
├── miow 0.2.2
│   └── mio 0.6.23
└── mio 0.6.23

https://crates.io/crates/cargo-audit

Is there any interest in migrating to the socket2 crate ?
Edit: guessing that updating the mio dependency would eliminate this.

Library should signal write-readiness on WouldBlock error

I've been using yup-hyper-mock a fair bit in a restrained docker environment (thanks for the library!). Unfortunately, I've discovered that sometimes hyper will not flush its buffer before a write is triggered in yup_hyper_mock, causing the mock library to never process the server headers when they are flushed, thereby hanging the process.

It only happens sometimes, the logs show:

$ cargo test -- --test-threads 1 --test container::tests::test_kill_container 2>&1 | less
test container::tests::test_kill_container ... [2018-12-04T11:33:23Z DEBUG bollard::uri] Parsing uri: unix://5f/containers/postgres/kill?signal=SIGKILL, client_type: Unix, socket: _
[2018-12-04T11:33:23Z TRACE hyper::client::pool] checkout waiting for idle connection: "unix://5f"
[2018-12-04T11:33:23Z DEBUG yup_hyper_mock] HostToReplyConnector::connect(Destination { uri: unix://5f/containers/postgres/kill?signal=SIGKILL })
[2018-12-04T11:33:23Z TRACE hyper::client::conn] client handshake HTTP/1
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=false
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=false
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::role] Client::encode method=POST, body=None
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::io] detected no usage of vectored write, flattening
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:33:23Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:33:23Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:33:23Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:33:23Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:33:23Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:33:23Z TRACE hyper::proto::h1::conn] Conn::read_head
... 

This goes on until my self-imposed tokio deadline is triggered.

By comparison, when it does go through it should show something like:

test container::tests::test_kill_container ... [2018-12-04T11:45:32Z DEBUG bollard::uri] Parsing uri: unix://5f/containers/postgres/kill?signal=SIGKILL, client_type: Unix, socket: _
[2018-12-04T11:45:32Z TRACE hyper::client::pool] checkout waiting for idle connection: "unix://5f"
[2018-12-04T11:45:32Z DEBUG yup_hyper_mock] HostToReplyConnector::connect(Destination { uri: unix://5f/containers/postgres/kill?signal=SIGKILL })
[2018-12-04T11:45:32Z TRACE hyper::client::conn] client handshake HTTP/1
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=false
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=false
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Not ready for read yet
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::role] Client::encode method=POST, body=None
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Request data: POST /containers/postgres/kill?signal=SIGKILL HTTP/1.1
content-type: application/json
host: 5f


[2018-12-04T11:45:32Z TRACE hyper::proto::h1::io] detected no usage of vectored write, flattening
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::io] flushed 100 bytes
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] flushed({role=client}): State { reading: Init, writing: KeepAlive, keep_alive: Busy, error: None }
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] flushed({role=client}): State { reading: Init, writing: KeepAlive, keep_alive: Busy, error: None }
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] Conn::read_head
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Buffer size: 8192, Data size: 85, Pos: 0
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Read 85 bytes: 'HTTP/1.1 200 OK
Server: mock1
Content-Type: application/json
Content-Length: 0

'
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::io] read 85 bytes
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::role] Response.parse([Header; 100], [u8; 85])
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::role] Response.parse Complete(85)
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::io] parsed 3 headers
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::conn] incoming body is empty
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Buffer size: 8192, Data size: 85, Pos: 85
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Read 0 bytes: ''
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::io] read 0 bytes
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=false
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Buffer size: 8192, Data size: 85, Pos: 85
[2018-12-04T11:45:32Z TRACE yup_hyper_mock::streams] Read 0 bytes: ''
[2018-12-04T11:45:32Z DEBUG hyper::proto::h1::io] read 0 bytes
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] try_io_read; found EOF on connection: State { reading: Init, writing: Init, keep_alive: Idle, error: None }
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] State::close_read()
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] flushed({role=client}): State { reading: Closed, writing: Init, keep_alive: Disabled, error: None }
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] read_keep_alive; is_mid_message=true
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] flushed({role=client}): State { reading: Closed, writing: Init, keep_alive: Disabled, error: None }
[2018-12-04T11:45:32Z TRACE hyper::proto::h1::conn] shut down IO complete

After some debugging, I realised the write was receiving a WouldBlock Error, so I've tried and solved the issue by subsequently calling https://docs.rs/tokio-reactor/0.1.2/tokio_reactor/struct.PollEvented.html#method.clear_write_ready

Remove dependency on `$crate` metavar

I am not sure if this is possible, given how this macro is being used, but I got confused when
my tests would only compile when I had set $crate[ref] to mock.

#[cfg(test)] #[macro_use]
extern crate yup_hyper_mock as mock;

Here is the error when the above was not set:

<mocks macros>:11:1: 11:5 error: failed to resolve. Maybe a missing `extern crate mock`?
<mocks macros>:11 :: mock:: MockStream {
                  ^~~~
<mocks macros>:1:1: 14:68 note: in expansion of mock_connector!
src/lib.rs:66:5: 76:8 note: expansion site
<mocks macros>:11:1: 11:21 error: `mock::MockStream` does not name a structure
<mocks macros>:11 :: mock:: MockStream {
                  ^~~~~~~~~~~~~~~~~~~~
<mocks macros>:1:1: 14:68 note: in expansion of mock_connector!
src/lib.rs:66:5: 76:8 note: expansion site
error: aborting due to 2 previous errors

Thanks!

Hyper 1.x upgrade

Is there any ongoing work to upgrade this crate to support the recent release of Hyper 1.x, or is there any appetite to receive PR's in that regard ?

I haven't made any headway into this yet, but identified that it would be needed to update Bollard, which I'm currently working on.

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.