From c51d7faa0ad46f9ebbd7f9eeaf784bb584223533 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 11:38:30 +0200 Subject: [PATCH 01/22] Remove dependency to real HTTP client in local mode --- .github/workflows/build.yml | 37 +++++++++-- CHANGELOG.md | 19 ++++++ Cargo.toml | 29 ++++---- Dockerfile | 2 +- Makefile | 15 +++++ README.md | 4 +- src/api/adapter/local.rs | 35 ++++++++-- src/api/adapter/mod.rs | 61 +---------------- src/api/adapter/standalone.rs | 66 +++++++++++++++++-- src/api/mod.rs | 6 +- src/api/server.rs | 12 +++- src/lib.rs | 20 ++---- src/server/matchers/mod.rs | 24 +++++++ src/server/mod.rs | 5 +- tests/examples/binary_body_tests.rs | 3 +- tests/examples/mass_tests.rs | 31 +++++++++ tests/examples/mod.rs | 7 +- ...iserver_tests.rs => multi_server_tests.rs} | 0 tests/internal/loop_test.rs | 5 +- tests/internal/mod.rs | 3 +- 20 files changed, 270 insertions(+), 114 deletions(-) create mode 100644 Makefile create mode 100644 tests/examples/mass_tests.rs rename tests/examples/{multiserver_tests.rs => multi_server_tests.rs} (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6e2903b..c7dee3b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,34 +5,57 @@ name: Build concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true - + jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] rust: - - stable - - beta - - nightly - - 1.64.0 # MSRV + # Default features enabled + - version: stable + - version: beta + - version: nightly + - version: 1.65.0 + # Also remote feature enabled + - version: stable + features: remote + - version: beta + features: remote + - version: nightly + features: remote + - version: 1.70.0 + features: remote + steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: ${{ matrix.rust }} + toolchain: ${{ matrix.rust.version }} override: true components: rustfmt, clippy + - name: Set feature arguments + id: set_features + run: | + if [ "${{ matrix.rust.features }}" == "remote" ]; then + echo "::set-output name=FEATURES_ARGS::--features remote" + else + echo "::set-output name=FEATURES_ARGS::" + fi + - uses: actions-rs/cargo@v1 with: command: build + args: ${{ steps.set_features.outputs.FEATURES_ARGS }} - uses: actions-rs/cargo@v1 with: command: test + args: ${{ steps.set_features.outputs.FEATURES_ARGS }} - uses: actions-rs/cargo@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index d6f76229..994a74f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## Version 0.7.0 + +- **BREAKING CHANGES**: + - For connecting to **remote** httpmock servers during tests using any of the `connect` methods like + [MockServer::connect](struct.MockServer.html#method.connect), + [MockServer::connect_async](struct.MockServer.html#method.connect_async), + [MockServer::connect_async](struct.MockServer.html#method.connect_from_env), or + [MockServer::connect_from_env](struct.MockServer.html#method.connect_from_env_async), you must now activate the + `remote` feature. This feature is not enabled by default. + +- Improvements: + - The dependency tree has been significantly slimmed down when the `remote` feature is not enabled. + - If the new `remote` feature is not enabled, `httpmock` no longer has a dependency on a real HTTP client. + As a result, certain [TLS issues previously reported by users](https://github.com/alexliesenfeld/httpmock/issues/82) + should no longer arise. + +- This release also updates all dependencies to the most recent version. +- The minimum Rust version has been bumped to 1.65 (and 1.70 for the standalone mode). + ## Version 0.6.8 - This is a maintenance release that updates all dependencies to the most recent version. diff --git a/Cargo.toml b/Cargo.toml index b81c9ecb..35ef5aa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,12 +15,8 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_regex = "1.1" lazy_static = "1.4" -hyper = { version = "0.14", features = ["server", "http1", "tcp"] } -tokio = { version = "1.29", features = ["sync", "macros", "rt-multi-thread", "signal"] } -isahc = "1.7" - base64 = "0.21" -regex = "1.9" +regex = "1.10" log = "0.4" url = "2.4" assert-json-diff = "2.0" @@ -28,32 +24,39 @@ async-trait = "0.1" async-object-pool = "0.1" crossbeam-utils = "0.8" futures-util = "0.3" -similar = "2.2" +similar = "2.3" levenshtein = "1.0" form_urlencoded = "1.2" +hyper = { version = "0.14", features = ["server", "http1", "tcp"] } +tokio = { version = "1.33", features = ["sync", "macros", "rt-multi-thread", "signal"] } + +isahc = { version = "1.7", optional = true } basic-cookies = { version = "0.1", optional = true } colored = { version = "2.0", optional = true } -clap = { version = "4.3", features = ["derive", "env"], optional = true } +clap = { version = "4.4", features = ["derive", "env"], optional = true } env_logger = { version = "0.10", optional = true } serde_yaml = { version = "0.9", optional = true } +async-std = { version = "1.12", features = ["attributes", "unstable"] } [dev-dependencies] env_logger = "0.10" tokio-test = "0.4" -async-std = { version = "1.12", features = ["attributes", "unstable"] } -isahc = { version = "1.7", features = ["json"] } -syn = { version = "2.0", features = ["full"] } quote = "1.0" -actix-rt = "2.8" +actix-rt = "2.9" colored = "2.0" -ureq = "2.7" +ureq = "2.8" + +isahc = { version = "1.7", features = ["json"] } +syn = { version = "2.0", features = ["full"] } +reqwest = "0.11.22" [features] default = ["cookies"] -standalone = ["clap", "env_logger", "serde_yaml"] +standalone = ["clap", "env_logger", "serde_yaml", "remote"] color = ["colored"] cookies = ["basic-cookies"] +remote = ["isahc"] [[bin]] name = "httpmock" diff --git a/Dockerfile b/Dockerfile index dfbbd24b..930103ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ================================================================================ # Builder # ================================================================================ -FROM rust:1.64 as builder +FROM rust:1.70 as builder WORKDIR /usr/src/httpmock COPY Cargo.toml . diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3412ae38 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +.PHONY: build +build: + cargo build + +.PHONY: test-local +test-local: + cargo test + +.PHONY: test-remote +test-local: + cargo test --features=remote + +.PHONY: build-docker +build-docker: + docker build -t alexliesenfeld/httpmock:latest . \ No newline at end of file diff --git a/README.md b/README.md index 8f945a81..2c6c0536 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![codecov](https://codecov.io/gh/alexliesenfeld/httpmock/branch/master/graph/badge.svg)](https://codecov.io/gh/alexliesenfeld/httpmock) [![crates.io](https://img.shields.io/crates/d/httpmock.svg)](https://crates.io/crates/httpmock) [![Mentioned in Awesome](https://camo.githubusercontent.com/e5d3197f63169393ee5695f496402136b412d5e3b1d77dc5aa80805fdd5e7edb/68747470733a2f2f617765736f6d652e72652f6d656e74696f6e65642d62616467652e737667)](https://github.com/rust-unofficial/awesome-rust#testing) -[![Rust](https://img.shields.io/badge/rust-1.64%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1540-2021-07-29) +[![Rust](https://img.shields.io/badge/rust-1.65%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1540-2021-07-29) @@ -44,7 +44,7 @@ Add `httpmock` to `Cargo.toml`: ```toml [dev-dependencies] -httpmock = "0.6" +httpmock = "0.7" ``` You can then use `httpmock` as follows: diff --git a/src/api/adapter/local.rs b/src/api/adapter/local.rs index ea5fc2fb..9d51dbd4 100644 --- a/src/api/adapter/local.rs +++ b/src/api/adapter/local.rs @@ -3,11 +3,15 @@ use std::fmt::Debug; use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; +use async_std::io::WriteExt; use async_trait::async_trait; -use isahc::prelude::*; -use crate::api::adapter::{build_http_client, http_ping, InternalHttpClient, MockServerAdapter}; +use async_std::net::TcpStream; +use async_std::prelude::*; + +use crate::api::adapter::{MockServerAdapter}; + use crate::common::data::{ActiveMock, ClosestMatch, MockDefinition, MockRef, RequestRequirements}; use crate::server::web::handlers::{ add_new_mock, delete_all_mocks, delete_history, delete_one_mock, read_one_mock, verify, @@ -17,16 +21,13 @@ use crate::server::MockServerState; pub struct LocalMockServerAdapter { pub addr: SocketAddr, local_state: Arc, - client: Arc, } impl LocalMockServerAdapter { pub fn new(addr: SocketAddr, local_state: Arc) -> Self { - let client = build_http_client(); LocalMockServerAdapter { addr, local_state, - client, } } } @@ -81,6 +82,28 @@ impl MockServerAdapter for LocalMockServerAdapter { } async fn ping(&self) -> Result<(), String> { - http_ping(&self.addr, self.client.borrow()).await + let addr = self.addr.to_string(); + + let mut stream = TcpStream::connect(&addr).await + .map_err(|err| format!("Cannot connect to mock server: {}", err))?; + + let request = format!( + "GET /__httpmock__/ping HTTP/1.1\r\nHost: {}\r\nConnection: close\r\n\r\n", + addr + ); + + stream.write_all(request.as_bytes()).await + .map_err(|err| format!("Cannot send request to mock server: {}", err))?; + + let mut buf = vec![0u8; 1024]; + stream.read(&mut buf).await + .map_err(|err| format!("Cannot read response from mock server: {}", err))?; + + let response = String::from_utf8_lossy(&buf); + if !response.contains("200 OK") { + return Err(format!("Unexpected mock server response. Expected '{}' to contain '200 OK'", response)) + } + + Ok(()) } } diff --git a/src/api/adapter/mod.rs b/src/api/adapter/mod.rs index c8ef08bf..7aca9396 100644 --- a/src/api/adapter/mod.rs +++ b/src/api/adapter/mod.rs @@ -4,9 +4,7 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; -use isahc::http::Request; -use isahc::prelude::Configurable; -use isahc::{AsyncReadResponseExt, ResponseExt}; + use serde::{Deserialize, Serialize}; use crate::common::data::{ActiveMock, ClosestMatch, MockDefinition, MockRef, RequestRequirements}; @@ -15,13 +13,13 @@ use crate::server::web::handlers::{ }; pub mod local; + +#[cfg(feature = "remote")] pub mod standalone; /// Type alias for [regex::Regex](../regex/struct.Regex.html). pub type Regex = regex::Regex; -pub type InternalHttpClient = isahc::HttpClient; - /// Represents an HTTP method. #[derive(Serialize, Deserialize, Debug)] pub enum Method { @@ -80,56 +78,3 @@ pub trait MockServerAdapter { async fn delete_history(&self) -> Result<(), String>; async fn ping(&self) -> Result<(), String>; } - -async fn http_ping( - server_addr: &SocketAddr, - http_client: &InternalHttpClient, -) -> Result<(), String> { - let request_url = format!("http://{}/__httpmock__/ping", server_addr); - let request = Request::builder() - .method("GET") - .uri(request_url) - .body("".to_string()) - .unwrap(); - - let (status, _body) = match execute_request(request, http_client).await { - Err(err) => return Err(format!("cannot send request to mock server: {}", err)), - Ok(sb) => sb, - }; - - if status != 200 { - return Err(format!( - "Could not create mock. Mock server response: status = {}", - status - )); - } - - Ok(()) -} - -async fn execute_request( - req: Request, - http_client: &InternalHttpClient, -) -> Result<(u16, String), String> { - let mut response = match http_client.send_async(req).await { - Err(err) => return Err(format!("cannot send request to mock server: {}", err)), - Ok(r) => r, - }; - - // Evaluate the response status - let body = match response.text().await { - Err(err) => return Err(format!("cannot send request to mock server: {}", err)), - Ok(b) => b, - }; - - Ok((response.status().as_u16(), body)) -} - -fn build_http_client() -> Arc { - Arc::new( - InternalHttpClient::builder() - .tcp_keepalive(Duration::from_secs(60 * 60 * 24)) - .build() - .expect("Cannot build HTTP client"), - ) -} diff --git a/src/api/adapter/standalone.rs b/src/api/adapter/standalone.rs index 3633a448..ad882591 100644 --- a/src/api/adapter/standalone.rs +++ b/src/api/adapter/standalone.rs @@ -1,13 +1,17 @@ use std::borrow::Borrow; use std::net::SocketAddr; use std::sync::Arc; +use std::time::Duration; + use async_trait::async_trait; -use isahc::Request; +use isahc::config::Configurable; +use isahc::{AsyncReadResponseExt, Request, ResponseExt}; +use crate::api::MockServerAdapter; + +pub type InternalHttpClient = isahc::HttpClient; + -use crate::api::adapter::{ - build_http_client, execute_request, http_ping, InternalHttpClient, MockServerAdapter, -}; use crate::common::data::{ActiveMock, ClosestMatch, MockDefinition, MockRef, RequestRequirements}; #[derive(Debug)] @@ -241,3 +245,57 @@ impl MockServerAdapter for RemoteMockServerAdapter { http_ping(&self.addr, self.http_client.borrow()).await } } + + +async fn http_ping( + server_addr: &SocketAddr, + http_client: &InternalHttpClient, +) -> Result<(), String> { + let request_url = format!("http://{}/__httpmock__/ping", server_addr); + let request = Request::builder() + .method("GET") + .uri(request_url) + .body("".to_string()) + .unwrap(); + + let (status, _body) = match execute_request(request, http_client).await { + Err(err) => return Err(format!("cannot send request to mock server: {}", err)), + Ok(sb) => sb, + }; + + if status != 200 { + return Err(format!( + "Could not create mock. Mock server response: status = {}", + status + )); + } + + Ok(()) +} + +async fn execute_request( + req: Request, + http_client: &InternalHttpClient, +) -> Result<(u16, String), String> { + let mut response = match http_client.send_async(req).await { + Err(err) => return Err(format!("cannot send request to mock server: {}", err)), + Ok(r) => r, + }; + + // Evaluate the response status + let body = match response.text().await { + Err(err) => return Err(format!("cannot send request to mock server: {}", err)), + Ok(b) => b, + }; + + Ok((response.status().as_u16(), body)) +} + +fn build_http_client() -> Arc { + Arc::new( + InternalHttpClient::builder() + .tcp_keepalive(Duration::from_secs(60 * 60 * 24)) + .build() + .expect("Cannot build HTTP client"), + ) +} diff --git a/src/api/mod.rs b/src/api/mod.rs index fcbdc063..ef84779a 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -2,9 +2,13 @@ #![allow(clippy::needless_lifetimes)] pub use adapter::{ - local::LocalMockServerAdapter, standalone::RemoteMockServerAdapter, Method, MockServerAdapter, + local::LocalMockServerAdapter, Method, MockServerAdapter, Regex, }; + +#[cfg(feature = "remote")] +pub use adapter::{standalone::RemoteMockServerAdapter}; + pub use mock::{Mock, MockExt}; pub use server::MockServer; pub use spec::{Then, When}; diff --git a/src/api/server.rs b/src/api/server.rs index face2068..7c7e8658 100644 --- a/src/api/server.rs +++ b/src/api/server.rs @@ -1,5 +1,7 @@ use crate::api::spec::{Then, When}; -use crate::api::{LocalMockServerAdapter, MockServerAdapter, RemoteMockServerAdapter}; +use crate::api::{LocalMockServerAdapter, MockServerAdapter}; +#[cfg(feature = "remote")] +use crate::api::{RemoteMockServerAdapter}; use crate::common::data::{MockDefinition, MockServerHttpResponse, RequestRequirements}; use crate::common::util::{read_env, with_retry, Join}; use crate::server::{start_server, MockServerState}; @@ -42,6 +44,8 @@ impl MockServer { /// Asynchronously connects to a remote mock server that is running in standalone mode using /// the provided address of the form : (e.g. "127.0.0.1:8080") to establish /// the connection. + /// **Note**: This method requires the feature `remote` to be enabled. + #[cfg(feature = "remote")] pub async fn connect_async(address: &str) -> Self { let addr = address .to_socket_addrs() @@ -58,12 +62,16 @@ impl MockServer { /// Synchronously connects to a remote mock server that is running in standalone mode using /// the provided address of the form : (e.g. "127.0.0.1:8080") to establish /// the connection. + /// **Note**: This method requires the feature `remote` to be enabled. + #[cfg(feature = "remote")] pub fn connect(address: &str) -> Self { Self::connect_async(address).join() } /// Asynchronously connects to a remote mock server that is running in standalone mode using /// connection parameters stored in `HTTPMOCK_HOST` and `HTTPMOCK_PORT` environment variables. + /// **Note**: This method requires the feature `remote` to be enabled. + #[cfg(feature = "remote")] pub async fn connect_from_env_async() -> Self { let host = read_env("HTTPMOCK_HOST", "127.0.0.1"); let port = read_env("HTTPMOCK_PORT", "5000") @@ -74,6 +82,8 @@ impl MockServer { /// Synchronously connects to a remote mock server that is running in standalone mode using /// connection parameters stored in `HTTPMOCK_HOST` and `HTTPMOCK_PORT` environment variables. + /// **Note**: This method requires the feature `remote` to be enabled. + #[cfg(feature = "remote")] pub fn connect_from_env() -> Self { Self::connect_from_env_async().join() } diff --git a/src/lib.rs b/src/lib.rs index 470e91db..f0dfe1dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! //! ```toml //! [dev-dependencies] -//! httpmock = "0.6" +//! httpmock = "0.7" //! ``` //! //! You can then use `httpmock` as follows: @@ -145,7 +145,8 @@ //! Instead of using [MockServer::start](struct.MockServer.html#method.start), //! you need to connect to a remote server by using one of the `connect` methods (such as //! [MockServer::connect](struct.MockServer.html#method.connect) or -//! [MockServer::connect_from_env](struct.MockServer.html#method.connect_from_env)). +//! [MockServer::connect_from_env](struct.MockServer.html#method.connect_from_env)). **Note**: +//! These are only available with the `remote` feature **enabled**. //! //! ``` //! use httpmock::prelude::*; @@ -212,26 +213,17 @@ extern crate lazy_static; use std::borrow::BorrowMut; -use std::cell::Cell; -use std::net::{SocketAddr, ToSocketAddrs}; -use std::path::Path; -use std::rc::Rc; +use std::net::{ToSocketAddrs}; + use std::str::FromStr; -use std::sync::Arc; -use std::thread; -use async_object_pool::Pool; use serde::{Deserialize, Serialize}; -use serde_json::Value; -use tokio::task::LocalSet; -use tokio::time::Duration; use api::MockServerAdapter; use common::util::Join; -use api::{LocalMockServerAdapter, RemoteMockServerAdapter}; pub use api::{Method, Mock, MockExt, MockServer, Regex, Then, When}; -use server::{start_server, MockServerState}; + mod api; mod common; diff --git a/src/server/matchers/mod.rs b/src/server/matchers/mod.rs index 4bf05f44..0f3d94fd 100644 --- a/src/server/matchers/mod.rs +++ b/src/server/matchers/mod.rs @@ -76,3 +76,27 @@ where let actual = actual.map_or(String::new(), |x| x.to_string()); levenshtein::levenshtein(&expected, &actual) } + +pub(crate) fn distance_for_binary, B: AsRef<[u8]>>(a: &Option, b: &Option) -> usize { + match (a, b) { + (Some(a_val), Some(b_val)) => { + let a_slice = a_val.as_ref(); + let b_slice = b_val.as_ref(); + + let min_len = std::cmp::min(a_slice.len(), b_slice.len()); + let max_len = std::cmp::max(a_slice.len(), b_slice.len()); + + let mut differing_bytes = max_len - min_len; + for i in 0..min_len { + if a_slice[i] != b_slice[i] { + differing_bytes += 1; + } + } + + differing_bytes + }, + (Some(a_val), None) => a_val.as_ref().len(), + (None, Some(b_val)) => b_val.as_ref().len(), + (None, None) => 0, + } +} \ No newline at end of file diff --git a/src/server/mod.rs b/src/server/mod.rs index ce72e718..ef8ef149 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -469,8 +469,6 @@ where let server = Server::bind(&format!("{}:{}", host, port).parse().unwrap()).serve(new_service); let addr = server.local_addr(); - // And now add a graceful shutdown signal... - let graceful = server.with_graceful_shutdown(shutdown); if let Some(socket_addr_sender) = socket_addr_sender { if let Err(e) = socket_addr_sender.send(addr) { return Err(format!( @@ -480,6 +478,9 @@ where } } + // And now add a graceful shutdown signal... + let graceful = server.with_graceful_shutdown(shutdown); + log::info!("Listening on {}", addr); if let Err(e) = graceful.await { return Err(format!("Err: {}", e)); diff --git a/tests/examples/binary_body_tests.rs b/tests/examples/binary_body_tests.rs index 49d666e1..f302748d 100644 --- a/tests/examples/binary_body_tests.rs +++ b/tests/examples/binary_body_tests.rs @@ -10,10 +10,11 @@ fn binary_body_test() { let server = MockServer::start(); let m = server.mock(|when, then| { - when.path("/hello"); + when.method("GET").path("/hello"); then.status(200).body(binary_content); }); + // Act let mut response = isahc::get(server.url("/hello")).unwrap(); diff --git a/tests/examples/mass_tests.rs b/tests/examples/mass_tests.rs new file mode 100644 index 00000000..5db64790 --- /dev/null +++ b/tests/examples/mass_tests.rs @@ -0,0 +1,31 @@ +use httpmock::prelude::*; +use isahc::{prelude::*, Request}; + +#[test] +fn cookie_matching_test() { + // Arrange + let server = MockServer::start(); + + let mock = server.mock(|when, then| { + when.method(GET) + .path("/") + .cookie_exists("SESSIONID") + .cookie("SESSIONID", "298zf09hf012fh2"); + then.status(200); + }); + + // Act: Send the request and deserialize the response to JSON + let response = Request::get(&format!("http://{}", server.address())) + .header( + "Cookie", + "OTHERCOOKIE1=01234; SESSIONID=298zf09hf012fh2; OTHERCOOKIE2=56789; HttpOnly", + ) + .body(()) + .unwrap() + .send() + .unwrap(); + + // Assert + mock.assert(); + assert_eq!(response.status(), 200); +} diff --git a/tests/examples/mod.rs b/tests/examples/mod.rs index 1592f253..e9b66539 100644 --- a/tests/examples/mod.rs +++ b/tests/examples/mod.rs @@ -7,10 +7,13 @@ mod file_body_tests; mod getting_started_tests; mod headers_tests; mod json_body_tests; -mod multiserver_tests; +mod multi_server_tests; mod query_param_tests; mod showcase_tests; -mod standalone_tests; mod string_body_tests; mod url_matching_tests; + +#[cfg(feature = "remote")] mod x_www_form_urlencoded_tests; +#[cfg(feature = "remote")] +mod standalone_tests; \ No newline at end of file diff --git a/tests/examples/multiserver_tests.rs b/tests/examples/multi_server_tests.rs similarity index 100% rename from tests/examples/multiserver_tests.rs rename to tests/examples/multi_server_tests.rs diff --git a/tests/internal/loop_test.rs b/tests/internal/loop_test.rs index 3215bd94..92d71d8a 100644 --- a/tests/internal/loop_test.rs +++ b/tests/internal/loop_test.rs @@ -1,9 +1,12 @@ extern crate httpmock; -use crate::simulate_standalone_server; use httpmock::prelude::*; use isahc::get; +#[cfg(feature = "remote")] +use crate::simulate_standalone_server; + +#[cfg(feature = "remote")] #[test] fn loop_with_standalone_test() { // Arrange diff --git a/tests/internal/mod.rs b/tests/internal/mod.rs index 4cb7b0ec..cb006080 100644 --- a/tests/internal/mod.rs +++ b/tests/internal/mod.rs @@ -1,4 +1,5 @@ mod extensions_test; -mod large_body_test; mod loop_test; mod runtimes_test; +#[cfg(feature = "remote")] +mod large_body_test; \ No newline at end of file From f514bf1cad881d3fcf5ca135aa1fac2d7fae8159 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 11:48:54 +0200 Subject: [PATCH 02/22] Add separate build for remote flag --- .github/workflows/build.yml | 73 ++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7dee3b1..65e9692c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,54 +8,31 @@ concurrency: jobs: build: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] rust: - # Default features enabled - - version: stable - - version: beta - - version: nightly - - version: 1.65.0 - # Also remote feature enabled - - version: stable - features: remote - - version: beta - features: remote - - version: nightly - features: remote - - version: 1.70.0 - features: remote - + - stable + - beta + - nightly + - 1.64.0 # MSRV steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: ${{ matrix.rust.version }} + toolchain: ${{ matrix.rust }} override: true components: rustfmt, clippy - - name: Set feature arguments - id: set_features - run: | - if [ "${{ matrix.rust.features }}" == "remote" ]; then - echo "::set-output name=FEATURES_ARGS::--features remote" - else - echo "::set-output name=FEATURES_ARGS::" - fi - - uses: actions-rs/cargo@v1 with: command: build - args: ${{ steps.set_features.outputs.FEATURES_ARGS }} - uses: actions-rs/cargo@v1 with: command: test - args: ${{ steps.set_features.outputs.FEATURES_ARGS }} - uses: actions-rs/cargo@v1 with: @@ -67,6 +44,44 @@ jobs: command: clippy args: -- -D warnings + build-remote: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.70.0 # MSRV + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + components: rustfmt, clippy + + - uses: actions-rs/cargo@v1 + with: + command: build --features remote + + - uses: actions-rs/cargo@v1 + with: + command: test --features remote + + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + + docker: runs-on: ubuntu-latest steps: From eb357cebf95c609174f10a78dcbc7a78a8701c33 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 11:53:28 +0200 Subject: [PATCH 03/22] Fix remote build --- .github/workflows/build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65e9692c..0fa26781 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,11 +65,13 @@ jobs: - uses: actions-rs/cargo@v1 with: - command: build --features remote + command: build + args: --features remote - uses: actions-rs/cargo@v1 with: - command: test --features remote + command: test + args: --features remote - uses: actions-rs/cargo@v1 with: From be76fde3134d08594ff4f8e4c92ba69d14e3f966 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 11:55:08 +0200 Subject: [PATCH 04/22] Fix remote build --- .github/workflows/build.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fa26781..1f1064bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,6 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} override: true - components: rustfmt, clippy - uses: actions-rs/cargo@v1 with: @@ -73,17 +72,6 @@ jobs: command: test args: --features remote - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings - - docker: runs-on: ubuntu-latest steps: From 38bfc6d5190a899b62f049d04dd08725ccd5e143 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:03:41 +0200 Subject: [PATCH 05/22] Remove unused functions --- .github/workflows/coverage.yml | 2 +- src/server/matchers/mod.rs | 24 ------------------------ 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 22a8be97..810b2558 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -19,7 +19,7 @@ jobs: - name: Generate code coverage run: | - cargo +nightly tarpaulin --verbose --workspace --timeout 120 --out Xml + cargo +nightly tarpaulin --verbose --workspace --all-features --timeout 120 --out Xml - name: Upload to codecov.io uses: codecov/codecov-action@v2 diff --git a/src/server/matchers/mod.rs b/src/server/matchers/mod.rs index 0f3d94fd..4bf05f44 100644 --- a/src/server/matchers/mod.rs +++ b/src/server/matchers/mod.rs @@ -76,27 +76,3 @@ where let actual = actual.map_or(String::new(), |x| x.to_string()); levenshtein::levenshtein(&expected, &actual) } - -pub(crate) fn distance_for_binary, B: AsRef<[u8]>>(a: &Option, b: &Option) -> usize { - match (a, b) { - (Some(a_val), Some(b_val)) => { - let a_slice = a_val.as_ref(); - let b_slice = b_val.as_ref(); - - let min_len = std::cmp::min(a_slice.len(), b_slice.len()); - let max_len = std::cmp::max(a_slice.len(), b_slice.len()); - - let mut differing_bytes = max_len - min_len; - for i in 0..min_len { - if a_slice[i] != b_slice[i] { - differing_bytes += 1; - } - } - - differing_bytes - }, - (Some(a_val), None) => a_val.as_ref().len(), - (None, Some(b_val)) => b_val.as_ref().len(), - (None, None) => 0, - } -} \ No newline at end of file From e63177dbf5ba85423bc28fb8ab4aaeaae199a516 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:06:25 +0200 Subject: [PATCH 06/22] Remove unused functions --- .github/workflows/build.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f1064bf..995e92d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,9 +8,11 @@ concurrency: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + name: build-${{ matrix.os }}-${{ matrix.rust }} strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] rust: - stable - beta @@ -45,9 +47,11 @@ jobs: args: -- -D warnings build-remote: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + name: build-remote-${{ matrix.os }}-${{ matrix.rust }} strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] rust: - stable - beta From bd1418577caf043d96f220a731b11f635e2f34a2 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:07:50 +0200 Subject: [PATCH 07/22] Format code --- src/api/adapter/local.rs | 25 +++++++++++++++---------- src/api/adapter/standalone.rs | 5 +---- src/api/mod.rs | 7 ++----- src/api/server.rs | 4 ++-- src/lib.rs | 3 +-- tests/examples/binary_body_tests.rs | 1 - tests/examples/mod.rs | 4 ++-- tests/internal/mod.rs | 4 ++-- 8 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/api/adapter/local.rs b/src/api/adapter/local.rs index 9d51dbd4..b1700600 100644 --- a/src/api/adapter/local.rs +++ b/src/api/adapter/local.rs @@ -1,16 +1,16 @@ +use async_std::io::WriteExt; use std::borrow::Borrow; use std::fmt::Debug; use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; -use async_std::io::WriteExt; use async_trait::async_trait; use async_std::net::TcpStream; use async_std::prelude::*; -use crate::api::adapter::{MockServerAdapter}; +use crate::api::adapter::MockServerAdapter; use crate::common::data::{ActiveMock, ClosestMatch, MockDefinition, MockRef, RequestRequirements}; use crate::server::web::handlers::{ @@ -25,10 +25,7 @@ pub struct LocalMockServerAdapter { impl LocalMockServerAdapter { pub fn new(addr: SocketAddr, local_state: Arc) -> Self { - LocalMockServerAdapter { - addr, - local_state, - } + LocalMockServerAdapter { addr, local_state } } } @@ -84,7 +81,8 @@ impl MockServerAdapter for LocalMockServerAdapter { async fn ping(&self) -> Result<(), String> { let addr = self.addr.to_string(); - let mut stream = TcpStream::connect(&addr).await + let mut stream = TcpStream::connect(&addr) + .await .map_err(|err| format!("Cannot connect to mock server: {}", err))?; let request = format!( @@ -92,16 +90,23 @@ impl MockServerAdapter for LocalMockServerAdapter { addr ); - stream.write_all(request.as_bytes()).await + stream + .write_all(request.as_bytes()) + .await .map_err(|err| format!("Cannot send request to mock server: {}", err))?; let mut buf = vec![0u8; 1024]; - stream.read(&mut buf).await + stream + .read(&mut buf) + .await .map_err(|err| format!("Cannot read response from mock server: {}", err))?; let response = String::from_utf8_lossy(&buf); if !response.contains("200 OK") { - return Err(format!("Unexpected mock server response. Expected '{}' to contain '200 OK'", response)) + return Err(format!( + "Unexpected mock server response. Expected '{}' to contain '200 OK'", + response + )); } Ok(()) diff --git a/src/api/adapter/standalone.rs b/src/api/adapter/standalone.rs index ad882591..fab076a0 100644 --- a/src/api/adapter/standalone.rs +++ b/src/api/adapter/standalone.rs @@ -3,15 +3,13 @@ use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; - +use crate::api::MockServerAdapter; use async_trait::async_trait; use isahc::config::Configurable; use isahc::{AsyncReadResponseExt, Request, ResponseExt}; -use crate::api::MockServerAdapter; pub type InternalHttpClient = isahc::HttpClient; - use crate::common::data::{ActiveMock, ClosestMatch, MockDefinition, MockRef, RequestRequirements}; #[derive(Debug)] @@ -246,7 +244,6 @@ impl MockServerAdapter for RemoteMockServerAdapter { } } - async fn http_ping( server_addr: &SocketAddr, http_client: &InternalHttpClient, diff --git a/src/api/mod.rs b/src/api/mod.rs index ef84779a..68c650ef 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,13 +1,10 @@ // TODO: Remove this at some point #![allow(clippy::needless_lifetimes)] -pub use adapter::{ - local::LocalMockServerAdapter, Method, MockServerAdapter, - Regex, -}; +pub use adapter::{local::LocalMockServerAdapter, Method, MockServerAdapter, Regex}; #[cfg(feature = "remote")] -pub use adapter::{standalone::RemoteMockServerAdapter}; +pub use adapter::standalone::RemoteMockServerAdapter; pub use mock::{Mock, MockExt}; pub use server::MockServer; diff --git a/src/api/server.rs b/src/api/server.rs index 7c7e8658..e665ede1 100644 --- a/src/api/server.rs +++ b/src/api/server.rs @@ -1,7 +1,7 @@ use crate::api::spec::{Then, When}; -use crate::api::{LocalMockServerAdapter, MockServerAdapter}; #[cfg(feature = "remote")] -use crate::api::{RemoteMockServerAdapter}; +use crate::api::RemoteMockServerAdapter; +use crate::api::{LocalMockServerAdapter, MockServerAdapter}; use crate::common::data::{MockDefinition, MockServerHttpResponse, RequestRequirements}; use crate::common::util::{read_env, with_retry, Join}; use crate::server::{start_server, MockServerState}; diff --git a/src/lib.rs b/src/lib.rs index f0dfe1dd..23c8565d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -213,7 +213,7 @@ extern crate lazy_static; use std::borrow::BorrowMut; -use std::net::{ToSocketAddrs}; +use std::net::ToSocketAddrs; use std::str::FromStr; @@ -224,7 +224,6 @@ use common::util::Join; pub use api::{Method, Mock, MockExt, MockServer, Regex, Then, When}; - mod api; mod common; mod server; diff --git a/tests/examples/binary_body_tests.rs b/tests/examples/binary_body_tests.rs index f302748d..bb0e640e 100644 --- a/tests/examples/binary_body_tests.rs +++ b/tests/examples/binary_body_tests.rs @@ -14,7 +14,6 @@ fn binary_body_test() { then.status(200).body(binary_content); }); - // Act let mut response = isahc::get(server.url("/hello")).unwrap(); diff --git a/tests/examples/mod.rs b/tests/examples/mod.rs index e9b66539..39b55c32 100644 --- a/tests/examples/mod.rs +++ b/tests/examples/mod.rs @@ -14,6 +14,6 @@ mod string_body_tests; mod url_matching_tests; #[cfg(feature = "remote")] -mod x_www_form_urlencoded_tests; +mod standalone_tests; #[cfg(feature = "remote")] -mod standalone_tests; \ No newline at end of file +mod x_www_form_urlencoded_tests; diff --git a/tests/internal/mod.rs b/tests/internal/mod.rs index cb006080..6733e7a2 100644 --- a/tests/internal/mod.rs +++ b/tests/internal/mod.rs @@ -1,5 +1,5 @@ mod extensions_test; +#[cfg(feature = "remote")] +mod large_body_test; mod loop_test; mod runtimes_test; -#[cfg(feature = "remote")] -mod large_body_test; \ No newline at end of file From 8087fb7cab4b41dc74ea2dab49b2853f90841cc4 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:10:48 +0200 Subject: [PATCH 08/22] Bump MSRV for local build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 995e92d1..2d359652 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: - stable - beta - nightly - - 1.64.0 # MSRV + - 1.65.0 # MSRV steps: - uses: actions/checkout@v2 From 025eaf4f2315402474fa89f553cb9c068f6bd526 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:15:25 +0200 Subject: [PATCH 09/22] Bump MSRV for local build --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d359652..ef0ad51b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,7 @@ jobs: build: runs-on: ${{ matrix.os }} name: build-${{ matrix.os }}-${{ matrix.rust }} + if: github.ref == 'refs/heads/master' || (matrix.os == 'ubuntu-latest' && matrix.rust == 'stable') strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] @@ -49,6 +50,7 @@ jobs: build-remote: runs-on: ${{ matrix.os }} name: build-remote-${{ matrix.os }}-${{ matrix.rust }} + if: github.ref == 'refs/heads/master' || (matrix.os == 'ubuntu-latest' && matrix.rust == 'stable') strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] From a4f30880cfc1fc74d5caecd16466909ac38d19ad Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 12:24:38 +0200 Subject: [PATCH 10/22] Bump MSRV for local build --- .github/workflows/build.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef0ad51b..a04a1d0d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,6 @@ jobs: build: runs-on: ${{ matrix.os }} name: build-${{ matrix.os }}-${{ matrix.rust }} - if: github.ref == 'refs/heads/master' || (matrix.os == 'ubuntu-latest' && matrix.rust == 'stable') strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] @@ -50,7 +49,6 @@ jobs: build-remote: runs-on: ${{ matrix.os }} name: build-remote-${{ matrix.os }}-${{ matrix.rust }} - if: github.ref == 'refs/heads/master' || (matrix.os == 'ubuntu-latest' && matrix.rust == 'stable') strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] @@ -93,11 +91,4 @@ jobs: with: context: . push: false - tags: alexliesenfeld/httpmock:latest - - name: Build and push - if: github.ref == 'refs/heads/master' - uses: docker/build-push-action@v4 - with: - context: . - push: true - tags: alexliesenfeld/httpmock:latest \ No newline at end of file + tags: alexliesenfeld/httpmock:build From f045741a96809cc3d3bb3b2b75fcc20975783048 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 13:28:46 +0200 Subject: [PATCH 11/22] Raise version. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 35ef5aa4..dab22d40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "httpmock" -version = "0.6.8" +version = "0.7.0" authors = ["Alexander Liesenfeld "] edition = "2018" description = "HTTP mocking library for Rust" From 4108159e112e02013a72e7a86a2abe7d5af41dcb Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:47:10 +0200 Subject: [PATCH 12/22] Improve build pipeline --- .github/workflows/build-branch.yml | 86 +++++++++++++++++++ .../workflows/{build.yml => build-master.yml} | 7 +- .github/workflows/docker.yml | 36 +++++--- 3 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/build-branch.yml rename .github/workflows/{build.yml => build-master.yml} (97%) diff --git a/.github/workflows/build-branch.yml b/.github/workflows/build-branch.yml new file mode 100644 index 00000000..25146d63 --- /dev/null +++ b/.github/workflows/build-branch.yml @@ -0,0 +1,86 @@ +on: + push: + branches: + - '*' + - '!master' + +name: Build Branch + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ${{ matrix.os }} + name: build-${{ matrix.os }}-${{ matrix.rust }} + strategy: + matrix: + os: [ubuntu-latest] + rust: + - 1.65.0 # MSRV + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + components: rustfmt, clippy + + - uses: actions-rs/cargo@v1 + with: + command: build + + - uses: actions-rs/cargo@v1 + with: + command: test + + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + + build-remote: + runs-on: ${{ matrix.os }} + name: build-remote-${{ matrix.os }}-${{ matrix.rust }} + strategy: + matrix: + os: [ubuntu-latest] + rust: + - 1.70.0 # MSRV + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --features remote + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --features remote + + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build development version + uses: docker/build-push-action@v4 + with: + context: . + push: false + tags: alexliesenfeld/httpmock:build diff --git a/.github/workflows/build.yml b/.github/workflows/build-master.yml similarity index 97% rename from .github/workflows/build.yml rename to .github/workflows/build-master.yml index a04a1d0d..3fb71228 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build-master.yml @@ -1,6 +1,9 @@ -on: push +on: + push: + branches: + - master -name: Build +name: Build Master concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 69a35744..b80f1e83 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,7 +1,14 @@ on: - push: - tags: - - 'v*.*.*' + workflow_dispatch: + inputs: + version: + description: 'Docker image version (e.g., 1.2.3)' + required: true + default: '' + latest: + description: 'latest' + required: false + default: 'true' name: Docker @@ -19,16 +26,19 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Write release version - run: | - TAG_NAME=${{ github.ref_name }} - DOCKER_IMAGE_VERSION="${TAG_NAME#v}" - echo "GitHub Version: ${TAG_NAME}" - echo "Docker Version: ${DOCKER_IMAGE_VERSION}" - echo "DOCKER_IMAGE_VERSION=${DOCKER_IMAGE_VERSION}" >> $GITHUB_ENV - - name: Build and push + - name: Build and push (provided version only) uses: docker/build-push-action@v4 + if: github.event.inputs.latest != 'true' with: context: . - push: true - tags: alexliesenfeld/httpmock:${{ env.DOCKER_IMAGE_VERSION }} + push: false + tags: alexliesenfeld/httpmock:${{ github.event.inputs.version }} + - name: Build and push (provided version + latest) + uses: docker/build-push-action@v4 + if: github.event.inputs.latest == 'true' + with: + context: . + push: false + tags: | + alexliesenfeld/httpmock:${{ github.event.inputs.version }}, + alexliesenfeld/httpmock:latest \ No newline at end of file From 32a51c4d2551121d646a0dcd85c31bfdbe40fc90 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:53:37 +0200 Subject: [PATCH 13/22] Improve build pipeline --- .github/workflows/build-branch.yml | 27 +++++++++++++++++++++++++++ .github/workflows/build-master.yml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/.github/workflows/build-branch.yml b/.github/workflows/build-branch.yml index 25146d63..1d0ffd6e 100644 --- a/.github/workflows/build-branch.yml +++ b/.github/workflows/build-branch.yml @@ -74,6 +74,33 @@ jobs: command: test args: --features remote + build-standalone: + runs-on: ${{ matrix.os }} + name: build-standalone-${{ matrix.os }}-${{ matrix.rust }} + strategy: + matrix: + os: [ubuntu-latest] + rust: + - 1.70.0 # MSRV + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --features standalone + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --features standalone + docker: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/build-master.yml b/.github/workflows/build-master.yml index 3fb71228..9110cc0f 100644 --- a/.github/workflows/build-master.yml +++ b/.github/workflows/build-master.yml @@ -79,6 +79,36 @@ jobs: command: test args: --features remote + build-standalone: + runs-on: ${{ matrix.os }} + name: build-standalone-${{ matrix.os }}-${{ matrix.rust }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + rust: + - stable + - beta + - nightly + - 1.70.0 # MSRV + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --features standalone + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --features standalone + docker: runs-on: ubuntu-latest steps: From 4ac28629240c9e91e849ede2a6f4a856142ed4bc Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:54:57 +0200 Subject: [PATCH 14/22] Improve build pipeline --- .github/workflows/build-master.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build-master.yml b/.github/workflows/build-master.yml index 9110cc0f..71a4b0af 100644 --- a/.github/workflows/build-master.yml +++ b/.github/workflows/build-master.yml @@ -109,6 +109,11 @@ jobs: command: test args: --features standalone + - uses: actions-rs/cargo@v1 + with: + command: install + args: --features standalone --path . + docker: runs-on: ubuntu-latest steps: From 0511c11ee104ef6ce9012bb590b40929f712cc34 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:55:35 +0200 Subject: [PATCH 15/22] Improve build pipeline --- .github/workflows/coverage.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 810b2558..b877700c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,4 +1,7 @@ -on: push +on: + push: + branches: + - master name: Coverage From 4b6e04fe6d6c8a6ce72a65436d556e72bc8aebf8 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:55:50 +0200 Subject: [PATCH 16/22] Improve build pipeline --- .github/workflows/{coverage.yml => coverage-master.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{coverage.yml => coverage-master.yml} (97%) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage-master.yml similarity index 97% rename from .github/workflows/coverage.yml rename to .github/workflows/coverage-master.yml index b877700c..f3408f28 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage-master.yml @@ -3,7 +3,7 @@ on: branches: - master -name: Coverage +name: Coverage Master concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From 00df88b59f27b5fcfc81a935284ae8027115437b Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 20:56:15 +0200 Subject: [PATCH 17/22] Improve build pipeline --- .github/workflows/{docker.yml => docker-release.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{docker.yml => docker-release.yml} (100%) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker-release.yml similarity index 100% rename from .github/workflows/docker.yml rename to .github/workflows/docker-release.yml From 8899852b2bcd470d391e90d6f4c49fe7c0615e06 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 21:02:26 +0200 Subject: [PATCH 18/22] Improve build pipeline --- Cargo.toml | 2 +- Makefile | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dab22d40..7ae49a7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "httpmock" -version = "0.7.0" +version = "0.7.0-rc.1" authors = ["Alexander Liesenfeld "] edition = "2018" description = "HTTP mocking library for Rust" diff --git a/Makefile b/Makefile index 3412ae38..ccf9a77a 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,14 @@ test-local: test-local: cargo test --features=remote +.PHONY: test-standalone +test-standalone: + cargo test --features standalone + +.PHONY: test-all +test-all: + cargo test --all-features + .PHONY: build-docker build-docker: - docker build -t alexliesenfeld/httpmock:latest . \ No newline at end of file + docker build . \ No newline at end of file From 6bdb83c4a4f64ffa8ef3b345f88d503213f6d98b Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 21:13:55 +0200 Subject: [PATCH 19/22] Improve build pipeline --- .../workflows/{build-master.yml => full-build.yml} | 13 ++++++++++++- CHANGELOG.md | 12 ++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) rename .github/workflows/{build-master.yml => full-build.yml} (90%) diff --git a/.github/workflows/build-master.yml b/.github/workflows/full-build.yml similarity index 90% rename from .github/workflows/build-master.yml rename to .github/workflows/full-build.yml index 71a4b0af..80143b0e 100644 --- a/.github/workflows/build-master.yml +++ b/.github/workflows/full-build.yml @@ -2,6 +2,12 @@ on: push: branches: - master + workflow_dispatch: + inputs: + branch: + description: 'The target branch' + required: true + default: 'master' name: Build Master @@ -23,7 +29,8 @@ jobs: - 1.65.0 # MSRV steps: - uses: actions/checkout@v2 - + with: + ref: ${{ github.event.inputs.branch }} - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -62,6 +69,8 @@ jobs: - 1.70.0 # MSRV steps: - uses: actions/checkout@v2 + with: + ref: ${{ github.event.inputs.branch }} - uses: actions-rs/toolchain@v1 with: @@ -92,6 +101,8 @@ jobs: - 1.70.0 # MSRV steps: - uses: actions/checkout@v2 + with: + ref: ${{ github.event.inputs.branch }} - uses: actions-rs/toolchain@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 994a74f8..426342b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,11 @@ - **BREAKING CHANGES**: - For connecting to **remote** httpmock servers during tests using any of the `connect` methods like - [MockServer::connect](struct.MockServer.html#method.connect), - [MockServer::connect_async](struct.MockServer.html#method.connect_async), - [MockServer::connect_async](struct.MockServer.html#method.connect_from_env), or - [MockServer::connect_from_env](struct.MockServer.html#method.connect_from_env_async), you must now activate the - `remote` feature. This feature is not enabled by default. + [MockServer::connect](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect), + [MockServer::connect_async](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect_async), + [MockServer::connect_from_env](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect_from_env), or + [MockServer::connect_from_env_async](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect_from_env_async), + you must now activate the `remote` feature. This feature is not enabled by default. - Improvements: - The dependency tree has been significantly slimmed down when the `remote` feature is not enabled. @@ -17,7 +17,7 @@ should no longer arise. - This release also updates all dependencies to the most recent version. -- The minimum Rust version has been bumped to 1.65 (and 1.70 for the standalone mode). +- The minimum Rust version has been bumped to 1.65 (and 1.70 for the remote and standalone features). ## Version 0.6.8 From 9be10cfb104a0782e4c22f562d913cafee39ae7f Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 21:14:31 +0200 Subject: [PATCH 20/22] Improve build pipeline --- .github/workflows/full-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/full-build.yml b/.github/workflows/full-build.yml index 80143b0e..0f5e2c4e 100644 --- a/.github/workflows/full-build.yml +++ b/.github/workflows/full-build.yml @@ -9,7 +9,7 @@ on: required: true default: 'master' -name: Build Master +name: Full Build concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From f28f2469a047c40673262cf9efa0ce5f87cf74d3 Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 21:16:56 +0200 Subject: [PATCH 21/22] Improve build pipeline --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 426342b1..b192ee47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Version 0.7.0 - **BREAKING CHANGES**: - - For connecting to **remote** httpmock servers during tests using any of the `connect` methods like + - For connecting to **remote** `httpmock` servers during tests using any of the `connect` methods like [MockServer::connect](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect), [MockServer::connect_async](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect_async), [MockServer::connect_from_env](https://docs.rs/httpmock/latest/httpmock/struct.MockServer.html#method.connect_from_env), or From cde1cca2e00a7640c205fa6b555d7fd886d62d4d Mon Sep 17 00:00:00 2001 From: Alexander Liesenfeld Date: Sun, 15 Oct 2023 21:20:59 +0200 Subject: [PATCH 22/22] Set documented versions to RC temporarily --- README.md | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c6c0536..f3e09e32 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Add `httpmock` to `Cargo.toml`: ```toml [dev-dependencies] -httpmock = "0.7" +httpmock = "0.7.0-rc.1" ``` You can then use `httpmock` as follows: diff --git a/src/lib.rs b/src/lib.rs index 23c8565d..99a5b39a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! //! ```toml //! [dev-dependencies] -//! httpmock = "0.7" +//! httpmock = "0.7.0-rc.1" //! ``` //! //! You can then use `httpmock` as follows: