fix all the other tests

This commit is contained in:
Rob Ede 2021-03-25 11:45:13 +00:00
parent 3c06993401
commit 6c1d115ccd
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
30 changed files with 226 additions and 200 deletions

View File

@ -52,10 +52,10 @@ cookies = ["actix-http/cookies"]
secure-cookies = ["actix-http/secure-cookies"] secure-cookies = ["actix-http/secure-cookies"]
# openssl # openssl
openssl = ["tls-openssl", "actix-tls/accept", "actix-tls/openssl"] openssl = ["actix-tls/accept", "actix-tls/openssl"]
# rustls # rustls
rustls = ["tls-rustls", "actix-tls/accept", "actix-tls/rustls"] rustls = ["actix-tls/accept", "actix-tls/rustls"]
[[example]] [[example]]
name = "basic" name = "basic"
@ -85,7 +85,6 @@ actix-tls = { version = "3.0.0-beta.5", default-features = false, optional = tru
actix-web-codegen = "0.5.0-beta.2" actix-web-codegen = "0.5.0-beta.2"
actix-http = "3.0.0-beta.4" actix-http = "3.0.0-beta.4"
# awc = { version = "3.0.0-beta.3", default-features = false }
ahash = "0.7" ahash = "0.7"
bytes = "1" bytes = "1"
@ -104,11 +103,12 @@ serde_urlencoded = "0.7"
smallvec = "1.6" smallvec = "1.6"
socket2 = "0.4.0" socket2 = "0.4.0"
time = { version = "0.2.23", default-features = false, features = ["std"] } time = { version = "0.2.23", default-features = false, features = ["std"] }
tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
tls-rustls = { package = "rustls", version = "0.19.0", optional = true }
url = "2.1" url = "2.1"
[dev-dependencies] [dev-dependencies]
actix-test = "0.0.1"
awc = { version = "3.0.0-beta.3", features = ["openssl"] }
brotli2 = "0.3.2" brotli2 = "0.3.2"
criterion = "0.3" criterion = "0.3"
env_logger = "0.8" env_logger = "0.8"
@ -116,6 +116,8 @@ flate2 = "1.0.13"
rand = "0.8" rand = "0.8"
rcgen = "0.8" rcgen = "0.8"
serde_derive = "1.0" serde_derive = "1.0"
tls-openssl = { package = "openssl", version = "0.10.9" }
tls-rustls = { package = "rustls", version = "0.19.0" }
[profile.release] [profile.release]
lto = true lto = true
@ -123,13 +125,14 @@ opt-level = 3
codegen-units = 1 codegen-units = 1
[patch.crates-io] [patch.crates-io]
actix-web = { path = "." } actix-files = { path = "actix-files" }
actix-http = { path = "actix-http" } actix-http = { path = "actix-http" }
actix-http-test = { path = "actix-http-test" } actix-http-test = { path = "actix-http-test" }
actix-multipart = { path = "actix-multipart" }
actix-test = { path = "actix-test" }
actix-web = { path = "." }
actix-web-actors = { path = "actix-web-actors" } actix-web-actors = { path = "actix-web-actors" }
actix-web-codegen = { path = "actix-web-codegen" } actix-web-codegen = { path = "actix-web-codegen" }
actix-multipart = { path = "actix-multipart" }
actix-files = { path = "actix-files" }
awc = { path = "awc" } awc = { path = "awc" }
[[bench]] [[bench]]

View File

@ -35,3 +35,4 @@ percent-encoding = "2.1"
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-web = "4.0.0-beta.4" actix-web = "4.0.0-beta.4"
actix-test = "0.0.1"

View File

@ -413,7 +413,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_named_file_content_range_headers() { async fn test_named_file_content_range_headers() {
let srv = test::start(|| App::new().service(Files::new("/", "."))); let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
// Valid range header // Valid range header
let response = srv let response = srv
@ -438,7 +438,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_named_file_content_length_headers() { async fn test_named_file_content_length_headers() {
let srv = test::start(|| App::new().service(Files::new("/", "."))); let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
// Valid range header // Valid range header
let response = srv let response = srv
@ -477,7 +477,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_head_content_length_headers() { async fn test_head_content_length_headers() {
let srv = test::start(|| App::new().service(Files::new("/", "."))); let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
let response = srv.head("/tests/test.binary").send().await.unwrap(); let response = srv.head("/tests/test.binary").send().await.unwrap();

View File

@ -260,7 +260,7 @@ impl Drop for TestServer {
} }
} }
/// Get first available unused address /// Get a localhost socket address with random, unused port.
pub fn unused_addr() -> net::SocketAddr { pub fn unused_addr() -> net::SocketAddr {
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap(); let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap(); let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap();

View File

@ -1,11 +1,20 @@
[package] [package]
name = "actix-test" name = "actix-test"
version = "0.1.0" version = "0.0.1"
authors = ["Rob Ede <robjtede@icloud.com>"] authors = ["Rob Ede <robjtede@icloud.com>"]
edition = "2018" edition = "2018"
description = "Integration testing tools for Actix Web applications" description = "Integration testing tools for Actix Web applications"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
[features]
default = []
# rustls
rustls = ["tls-rustls", "actix-http/rustls"]
# openssl
openssl = ["tls-openssl", "actix-http/openssl"]
[dependencies] [dependencies]
actix-codec = "0.4.0-beta.1" actix-codec = "0.4.0-beta.1"
actix-http = { version = "3.0.0-beta.4", features = ["cookies"] } actix-http = { version = "3.0.0-beta.4", features = ["cookies"] }
@ -17,6 +26,9 @@ awc = { version = "3.0.0-beta.3", default-features = false, features = ["cookies
futures-core = { version = "0.3.7", default-features = false, features = ["std"] } futures-core = { version = "0.3.7", default-features = false, features = ["std"] }
futures-util = { version = "0.3.7", default-features = false, features = [] } futures-util = { version = "0.3.7", default-features = false, features = [] }
log = "0.4"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
serde_urlencoded = "0.7" serde_urlencoded = "0.7"
tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
tls-rustls = { package = "rustls", version = "0.19.0", optional = true }

View File

@ -15,7 +15,7 @@
//! //!
//! #[actix_rt::test] //! #[actix_rt::test]
//! async fn test_example() { //! async fn test_example() {
//! let srv = test::start(|| //! let srv = actix_test::start(||
//! App::new().service(my_handler) //! App::new().service(my_handler)
//! ); //! );
//! //!
@ -26,6 +26,11 @@
//! } //! }
//! ``` //! ```
#[cfg(feature = "openssl")]
extern crate tls_openssl as openssl;
#[cfg(feature = "rustls")]
extern crate tls_rustls as rustls;
use std::{fmt, net, sync::mpsc, thread, time}; use std::{fmt, net, sync::mpsc, thread, time};
use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Framed};
@ -34,9 +39,7 @@ use actix_http::{http::Method, ws, HttpService, Request};
use actix_service::{map_config, IntoServiceFactory, ServiceFactory}; use actix_service::{map_config, IntoServiceFactory, ServiceFactory};
use actix_web::{ use actix_web::{
dev::{AppConfig, MessageBody, Server, Service}, dev::{AppConfig, MessageBody, Server, Service},
rt, rt, web, Error, HttpResponse,
web::Bytes,
Error, HttpResponse,
}; };
use awc::{error::PayloadError, Client, ClientRequest, ClientResponse, Connector}; use awc::{error::PayloadError, Client, ClientRequest, ClientResponse, Connector};
use futures_core::Stream; use futures_core::Stream;
@ -47,29 +50,27 @@ pub use actix_web::test::{
read_body_json, read_response, read_response_json, TestRequest, read_body_json, read_response, read_response_json, TestRequest,
}; };
/// Start default test server. /// Start default [`TestServer`].
///
/// Test server is very simple server that simplify process of writing
/// integration tests cases for actix web applications.
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use actix_web::{web, test, App, HttpResponse, Error}; /// use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
/// ///
/// async fn my_handler() -> Result<HttpResponse, Error> { /// #[get("/")]
/// Ok(HttpResponse::Ok().into()) /// async fn my_handler() -> Result<impl Responder, Error> {
/// Ok(HttpResponse::Ok())
/// } /// }
/// ///
/// #[actix_rt::test] /// #[actix_rt::test]
/// async fn test_example() { /// async fn test_example() {
/// let srv = test::start( /// let srv = actix_test::start(||
/// || App::new().service( /// App::new().service(my_handler)
/// web::resource("/").to(my_handler))
/// ); /// );
/// ///
/// let req = srv.get("/"); /// let req = srv.get("/");
/// let response = req.send().await.unwrap(); /// let res = req.send().await.unwrap();
/// assert!(response.status().is_success()); ///
/// assert!(res.status().is_success());
/// } /// }
/// ``` /// ```
pub fn start<F, I, S, B>(factory: F) -> TestServer pub fn start<F, I, S, B>(factory: F) -> TestServer
@ -92,21 +93,23 @@ where
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use actix_web::{web, test, App, HttpResponse, Error, Responder}; /// use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
/// ///
/// #[get("/")]
/// async fn my_handler() -> Result<impl Responder, Error> { /// async fn my_handler() -> Result<impl Responder, Error> {
/// Ok(HttpResponse::Ok()) /// Ok(HttpResponse::Ok())
/// } /// }
/// ///
/// #[actix_rt::test] /// #[actix_rt::test]
/// async fn test_example() { /// async fn test_example() {
/// let srv = test::start_with(test::config().h1(), || /// let srv = actix_test::start_with(actix_test::config().h1(), ||
/// App::new().service(web::resource("/").to(my_handler)) /// App::new().service(my_handler)
/// ); /// );
/// ///
/// let req = srv.get("/"); /// let req = srv.get("/");
/// let response = req.send().await.unwrap(); /// let res = req.send().await.unwrap();
/// assert!(response.status().is_success()); ///
/// assert!(res.status().is_success());
/// } /// }
/// ``` /// ```
pub fn start_with<F, I, S, B>(cfg: TestServerConfig, factory: F) -> TestServer pub fn start_with<F, I, S, B>(cfg: TestServerConfig, factory: F) -> TestServer
@ -174,7 +177,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h1(map_config(factory(), |_| cfg.clone())) .h1(map_config(factory(), move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
HttpVer::Http2 => builder.listen("test", tcp, move || { HttpVer::Http2 => builder.listen("test", tcp, move || {
@ -182,7 +185,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h2(map_config(factory(), |_| cfg.clone())) .h2(map_config(factory(), move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
HttpVer::Both => builder.listen("test", tcp, move || { HttpVer::Both => builder.listen("test", tcp, move || {
@ -190,7 +193,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.finish(map_config(factory(), |_| cfg.clone())) .finish(map_config(factory(), move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
}, },
@ -201,7 +204,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h1(map_config(factory(), |_| cfg.clone())) .h1(map_config(factory(), move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
HttpVer::Http2 => builder.listen("test", tcp, move || { HttpVer::Http2 => builder.listen("test", tcp, move || {
@ -209,7 +212,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h2(map_config(factory(), |_| cfg.clone())) .h2(map_config(factory(), move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
HttpVer::Both => builder.listen("test", tcp, move || { HttpVer::Both => builder.listen("test", tcp, move || {
@ -217,7 +220,7 @@ where
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.finish(map_config(factory(), |_| cfg.clone())) .finish(map_config(factory(), move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
}, },
@ -277,7 +280,7 @@ enum HttpVer {
Both, Both,
} }
#[derive(Debug, Clone)] #[derive(Clone)]
enum StreamType { enum StreamType {
Tcp, Tcp,
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
@ -291,7 +294,7 @@ pub fn config() -> TestServerConfig {
TestServerConfig::default() TestServerConfig::default()
} }
#[derive(Debug, Clone)] #[derive(Clone)]
pub struct TestServerConfig { pub struct TestServerConfig {
tp: HttpVer, tp: HttpVer,
stream: StreamType, stream: StreamType,
@ -347,7 +350,10 @@ impl TestServerConfig {
} }
} }
/// Test server controller. /// A basic HTTP server controller that simplifies the process of writing integration tests for
/// Actix Web applications.
///
/// See [`start`] for usage example.
pub struct TestServer { pub struct TestServer {
addr: net::SocketAddr, addr: net::SocketAddr,
client: awc::Client, client: awc::Client,
@ -416,9 +422,9 @@ impl TestServer {
pub async fn load_body<S>( pub async fn load_body<S>(
&mut self, &mut self,
mut response: ClientResponse<S>, mut response: ClientResponse<S>,
) -> Result<Bytes, PayloadError> ) -> Result<web::Bytes, PayloadError>
where where
S: Stream<Item = Result<Bytes, PayloadError>> + Unpin + 'static, S: Stream<Item = Result<web::Bytes, PayloadError>> + Unpin + 'static,
{ {
response.body().limit(10_485_760).await response.body().limit(10_485_760).await
} }

View File

@ -29,5 +29,7 @@ tokio = { version = "1", features = ["sync"] }
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-test = "0.0.1"
env_logger = "0.8" env_logger = "0.8"
futures-util = { version = "0.3.7", default-features = false } futures-util = { version = "0.3.7", default-features = false }

View File

@ -1,5 +1,5 @@
use actix::prelude::*; use actix::prelude::*;
use actix_web::{test, web, App, HttpRequest}; use actix_web::{web, App, HttpRequest};
use actix_web_actors::*; use actix_web_actors::*;
use bytes::Bytes; use bytes::Bytes;
use futures_util::{SinkExt, StreamExt}; use futures_util::{SinkExt, StreamExt};
@ -24,7 +24,7 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for Ws {
#[actix_rt::test] #[actix_rt::test]
async fn test_simple() { async fn test_simple() {
let mut srv = test::start(|| { let mut srv = actix_test::start(|| {
App::new().service(web::resource("/").to( App::new().service(web::resource("/").to(
|req: HttpRequest, stream: web::Payload| async move { ws::start(Ws, &req, stream) }, |req: HttpRequest, stream: web::Payload| async move { ws::start(Ws, &req, stream) },
)) ))

View File

@ -21,6 +21,8 @@ proc-macro2 = "1"
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-web = "4.0.0-beta.4" actix-web = "4.0.0-beta.4"
actix-test = "0.0.1"
futures-util = { version = "0.3.7", default-features = false } futures-util = { version = "0.3.7", default-features = false }
trybuild = "1" trybuild = "1"
rustversion = "1" rustversion = "1"

View File

@ -3,7 +3,7 @@ use std::task::{Context, Poll};
use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform}; use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform};
use actix_web::http::header::{HeaderName, HeaderValue}; use actix_web::http::header::{HeaderName, HeaderValue};
use actix_web::{http, test, web::Path, App, Error, HttpResponse, Responder}; use actix_web::{http, web::Path, App, Error, HttpResponse, Responder};
use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, route, trace}; use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, route, trace};
use futures_util::future::{self, LocalBoxFuture}; use futures_util::future::{self, LocalBoxFuture};
@ -148,7 +148,7 @@ async fn get_wrap(_: Path<String>) -> impl Responder {
#[actix_rt::test] #[actix_rt::test]
async fn test_params() { async fn test_params() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new() App::new()
.service(get_param_test) .service(get_param_test)
.service(put_param_test) .service(put_param_test)
@ -170,7 +170,7 @@ async fn test_params() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body() { async fn test_body() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new() App::new()
.service(post_test) .service(post_test)
.service(put_test) .service(put_test)
@ -244,7 +244,7 @@ async fn test_body() {
#[actix_rt::test] #[actix_rt::test]
async fn test_auto_async() { async fn test_auto_async() {
let srv = test::start(|| App::new().service(auto_async)); let srv = actix_test::start(|| App::new().service(auto_async));
let request = srv.request(http::Method::GET, srv.url("/test")); let request = srv.request(http::Method::GET, srv.url("/test"));
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();
@ -253,7 +253,7 @@ async fn test_auto_async() {
#[actix_rt::test] #[actix_rt::test]
async fn test_wrap() { async fn test_wrap() {
let srv = test::start(|| App::new().service(get_wrap)); let srv = actix_test::start(|| App::new().service(get_wrap));
let request = srv.request(http::Method::GET, srv.url("/test/wrap")); let request = srv.request(http::Method::GET, srv.url("/test/wrap"));
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -1,7 +1,7 @@
use actix_web::{Responder, HttpResponse, App, test}; use actix_web::{Responder, HttpResponse, App};
use actix_web_codegen::*; use actix_web_codegen::*;
/// Docstrings shouldn't break anything. /// doc comments shouldn't break anything
#[get("/")] #[get("/")]
async fn index() -> impl Responder { async fn index() -> impl Responder {
HttpResponse::Ok() HttpResponse::Ok()
@ -9,7 +9,7 @@ async fn index() -> impl Responder {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
let srv = test::start(|| App::new().service(index)); let srv = actix_test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -7,9 +7,9 @@ async fn index() -> String {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test}; use actix_web::App;
let srv = test::start(|| App::new().service(index)); let srv = actix_test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -5,7 +5,7 @@ error: HTTP method defined more than once: `GET`
| ^^^^^ | ^^^^^
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-duplicate-method-fail.rs:12:49 --> $DIR/route-duplicate-method-fail.rs:12:55
| |
12 | let srv = test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -7,9 +7,9 @@ async fn index() -> String {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test}; use actix_web::App;
let srv = test::start(|| App::new().service(index)); let srv = actix_test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -7,7 +7,7 @@ error: The #[route(..)] macro requires at least one `method` attribute
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-missing-method-fail.rs:12:49 --> $DIR/route-missing-method-fail.rs:12:55
| |
12 | let srv = test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -7,9 +7,9 @@ async fn index() -> String {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test}; use actix_web::App;
let srv = test::start(|| App::new().service(index)); let srv = actix_test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -7,9 +7,9 @@ async fn index() -> String {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
use actix_web::{App, test}; use actix_web::App;
let srv = test::start(|| App::new().service(index)); let srv = actix_test::start(|| App::new().service(index));
let request = srv.get("/"); let request = srv.get("/");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -5,7 +5,7 @@ error: Unexpected HTTP method: `UNEXPECTED`
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0425]: cannot find value `index` in this scope error[E0425]: cannot find value `index` in this scope
--> $DIR/route-unexpected-method-fail.rs:12:49 --> $DIR/route-unexpected-method-fail.rs:12:55
| |
12 | let srv = test::start(|| App::new().service(index)); 12 | let srv = actix_test::start(|| App::new().service(index));
| ^^^^^ not found in this scope | ^^^^^ not found in this scope

View File

@ -1,4 +1,4 @@
use actix_web::{Responder, HttpResponse, App, test}; use actix_web::{Responder, HttpResponse, App};
use actix_web_codegen::*; use actix_web_codegen::*;
#[get("/config")] #[get("/config")]
@ -8,7 +8,7 @@ async fn config() -> impl Responder {
#[actix_web::main] #[actix_web::main]
async fn main() { async fn main() {
let srv = test::start(|| App::new().service(config)); let srv = actix_test::start(|| App::new().service(config));
let request = srv.get("/config"); let request = srv.get("/config");
let response = request.send().await.unwrap(); let response = request.send().await.unwrap();

View File

@ -72,6 +72,7 @@ actix-http-test = { version = "3.0.0-beta.3", features = ["openssl"] }
actix-utils = "3.0.0-beta.1" actix-utils = "3.0.0-beta.1"
actix-server = "2.0.0-beta.3" actix-server = "2.0.0-beta.3"
actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] } actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] }
actix-test = { version = "0.0.1", features = ["openssl", "rustls"] }
brotli2 = "0.3.2" brotli2 = "0.3.2"
env_logger = "0.8" env_logger = "0.8"

View File

@ -283,10 +283,9 @@ fn rebuild_uri(res: &ClientResponse, org_uri: Uri) -> Result<Uri, SendRequestErr
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_web::{test::start, web, App, Error, HttpResponse}; use actix_web::{web, App, Error, HttpResponse};
use super::*; use super::*;
use crate::ClientBuilder; use crate::ClientBuilder;
#[actix_rt::test] #[actix_rt::test]
@ -296,7 +295,7 @@ mod tests {
.wrap(Redirect::new().max_redirect_times(10)) .wrap(Redirect::new().max_redirect_times(10))
.finish(); .finish();
let srv = start(|| { let srv = actix_test::start(|| {
App::new() App::new()
.service(web::resource("/test").route(web::to(|| async { .service(web::resource("/test").route(web::to(|| async {
Ok::<_, Error>(HttpResponse::BadRequest()) Ok::<_, Error>(HttpResponse::BadRequest())
@ -323,7 +322,7 @@ mod tests {
.connector(crate::Connector::new()) .connector(crate::Connector::new())
.finish(); .finish();
let srv = start(|| { let srv = actix_test::start(|| {
App::new() App::new()
.service(web::resource("/").route(web::to(|| async { .service(web::resource("/").route(web::to(|| async {
Ok::<_, Error>( Ok::<_, Error>(

View File

@ -23,7 +23,7 @@ use actix_web::{
dev::{AppConfig, BodyEncoding}, dev::{AppConfig, BodyEncoding},
http::{header, Cookie}, http::{header, Cookie},
middleware::Compress, middleware::Compress,
test, web, App, Error, HttpMessage, HttpRequest, HttpResponse, web, App, Error, HttpMessage, HttpRequest, HttpResponse,
}; };
use awc::error::{JsonPayloadError, PayloadError, SendRequestError}; use awc::error::{JsonPayloadError, PayloadError, SendRequestError};
@ -51,7 +51,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
#[actix_rt::test] #[actix_rt::test]
async fn test_simple() { async fn test_simple() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR)))) App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
}); });
@ -77,7 +77,7 @@ async fn test_simple() {
#[actix_rt::test] #[actix_rt::test]
async fn test_json() { async fn test_json() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service( App::new().service(
web::resource("/").route(web::to(|_: web::Json<String>| HttpResponse::Ok())), web::resource("/").route(web::to(|_: web::Json<String>| HttpResponse::Ok())),
) )
@ -93,7 +93,7 @@ async fn test_json() {
#[actix_rt::test] #[actix_rt::test]
async fn test_form() { async fn test_form() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to( App::new().service(web::resource("/").route(web::to(
|_: web::Form<HashMap<String, String>>| HttpResponse::Ok(), |_: web::Form<HashMap<String, String>>| HttpResponse::Ok(),
))) )))
@ -112,7 +112,7 @@ async fn test_form() {
#[actix_rt::test] #[actix_rt::test]
async fn test_timeout() { async fn test_timeout() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| async { App::new().service(web::resource("/").route(web::to(|| async {
actix_rt::time::sleep(Duration::from_millis(200)).await; actix_rt::time::sleep(Duration::from_millis(200)).await;
Ok::<_, Error>(HttpResponse::Ok().body(STR)) Ok::<_, Error>(HttpResponse::Ok().body(STR))
@ -137,7 +137,7 @@ async fn test_timeout() {
#[actix_rt::test] #[actix_rt::test]
async fn test_timeout_override() { async fn test_timeout_override() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| async { App::new().service(web::resource("/").route(web::to(|| async {
actix_rt::time::sleep(Duration::from_millis(200)).await; actix_rt::time::sleep(Duration::from_millis(200)).await;
Ok::<_, Error>(HttpResponse::Ok().body(STR)) Ok::<_, Error>(HttpResponse::Ok().body(STR))
@ -161,7 +161,7 @@ async fn test_timeout_override() {
async fn test_response_timeout() { async fn test_response_timeout() {
use futures_util::stream::{once, StreamExt}; use futures_util::stream::{once, StreamExt};
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| async { App::new().service(web::resource("/").route(web::to(|| async {
Ok::<_, Error>( Ok::<_, Error>(
HttpResponse::Ok() HttpResponse::Ok()
@ -443,7 +443,7 @@ async fn test_connection_wait_queue_force_close() {
#[actix_rt::test] #[actix_rt::test]
async fn test_with_query_parameter() { async fn test_with_query_parameter() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").to(|req: HttpRequest| { App::new().service(web::resource("/").to(|req: HttpRequest| {
if req.query_string().contains("qp") { if req.query_string().contains("qp") {
HttpResponse::Ok() HttpResponse::Ok()
@ -463,7 +463,7 @@ async fn test_with_query_parameter() {
#[actix_rt::test] #[actix_rt::test]
async fn test_no_decompress() { async fn test_no_decompress() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new() App::new()
.wrap(Compress::default()) .wrap(Compress::default())
.service(web::resource("/").route(web::to(|| { .service(web::resource("/").route(web::to(|| {
@ -507,7 +507,7 @@ async fn test_no_decompress() {
#[actix_rt::test] #[actix_rt::test]
async fn test_client_gzip_encoding() { async fn test_client_gzip_encoding() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| { App::new().service(web::resource("/").route(web::to(|| {
let mut e = GzEncoder::new(Vec::new(), Compression::default()); let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(STR.as_ref()).unwrap(); e.write_all(STR.as_ref()).unwrap();
@ -530,7 +530,7 @@ async fn test_client_gzip_encoding() {
#[actix_rt::test] #[actix_rt::test]
async fn test_client_gzip_encoding_large() { async fn test_client_gzip_encoding_large() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| { App::new().service(web::resource("/").route(web::to(|| {
let mut e = GzEncoder::new(Vec::new(), Compression::default()); let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(STR.repeat(10).as_ref()).unwrap(); e.write_all(STR.repeat(10).as_ref()).unwrap();
@ -559,7 +559,7 @@ async fn test_client_gzip_encoding_large_random() {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|data: Bytes| { App::new().service(web::resource("/").route(web::to(|data: Bytes| {
let mut e = GzEncoder::new(Vec::new(), Compression::default()); let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write_all(&data).unwrap(); e.write_all(&data).unwrap();
@ -581,7 +581,7 @@ async fn test_client_gzip_encoding_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_client_brotli_encoding() { async fn test_client_brotli_encoding() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|data: Bytes| { App::new().service(web::resource("/").route(web::to(|data: Bytes| {
let mut e = BrotliEncoder::new(Vec::new(), 5); let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(&data).unwrap(); e.write_all(&data).unwrap();
@ -609,7 +609,7 @@ async fn test_client_brotli_encoding_large_random() {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|data: Bytes| { App::new().service(web::resource("/").route(web::to(|data: Bytes| {
let mut e = BrotliEncoder::new(Vec::new(), 5); let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(&data).unwrap(); e.write_all(&data).unwrap();
@ -632,7 +632,7 @@ async fn test_client_brotli_encoding_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_client_deflate_encoding() { async fn test_client_deflate_encoding() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: Bytes| { App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok() HttpResponse::Ok()
.encoding(http::ContentEncoding::Br) .encoding(http::ContentEncoding::Br)
@ -657,7 +657,7 @@ async fn test_client_deflate_encoding_large_random() {
.take(70_000) .take(70_000)
.collect::<String>(); .collect::<String>();
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: Bytes| { App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok() HttpResponse::Ok()
.encoding(http::ContentEncoding::Br) .encoding(http::ContentEncoding::Br)
@ -676,7 +676,7 @@ async fn test_client_deflate_encoding_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_client_streaming_explicit() { async fn test_client_streaming_explicit() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: web::Payload| { App::new().default_service(web::to(|body: web::Payload| {
HttpResponse::Ok() HttpResponse::Ok()
.encoding(http::ContentEncoding::Identity) .encoding(http::ContentEncoding::Identity)
@ -697,7 +697,7 @@ async fn test_client_streaming_explicit() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_streaming_implicit() { async fn test_body_streaming_implicit() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().default_service(web::to(|| { App::new().default_service(web::to(|| {
let body = stream::once(async { let body = stream::once(async {
Ok::<_, actix_http::Error>(Bytes::from_static(STR.as_bytes())) Ok::<_, actix_http::Error>(Bytes::from_static(STR.as_bytes()))
@ -733,7 +733,7 @@ async fn test_client_cookie_handling() {
let cookie1b = cookie1.clone(); let cookie1b = cookie1.clone();
let cookie2b = cookie2.clone(); let cookie2b = cookie2.clone();
let srv = test::start(move || { let srv = actix_test::start(move || {
let cookie1 = cookie1b.clone(); let cookie1 = cookie1b.clone();
let cookie2 = cookie2b.clone(); let cookie2 = cookie2b.clone();
@ -789,8 +789,7 @@ async fn test_client_cookie_handling() {
#[actix_rt::test] #[actix_rt::test]
async fn client_unread_response() { async fn client_unread_response() {
let addr = test::unused_addr(); let addr = actix_test::unused_addr();
let lst = std::net::TcpListener::bind(addr).unwrap(); let lst = std::net::TcpListener::bind(addr).unwrap();
std::thread::spawn(move || { std::thread::spawn(move || {
@ -819,7 +818,7 @@ async fn client_unread_response() {
#[actix_rt::test] #[actix_rt::test]
async fn client_basic_auth() { async fn client_basic_auth() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().route( App::new().route(
"/", "/",
web::to(|req: HttpRequest| { web::to(|req: HttpRequest| {
@ -847,7 +846,7 @@ async fn client_basic_auth() {
#[actix_rt::test] #[actix_rt::test]
async fn client_bearer_auth() { async fn client_bearer_auth() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().route( App::new().route(
"/", "/",
web::to(|req: HttpRequest| { web::to(|req: HttpRequest| {
@ -877,7 +876,7 @@ async fn client_bearer_auth() {
async fn test_local_address() { async fn test_local_address() {
let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let srv = test::start(move || { let srv = actix_test::start(move || {
App::new().service(web::resource("/").route(web::to( App::new().service(web::resource("/").route(web::to(
move |req: HttpRequest| async move { move |req: HttpRequest| async move {
assert_eq!(req.peer_addr().unwrap().ip(), ip); assert_eq!(req.peer_addr().unwrap().ip(), ip);

View File

@ -32,7 +32,7 @@ fn bench_async_burst(c: &mut Criterion) {
let rt = actix_rt::System::new(); let rt = actix_rt::System::new();
let srv = rt.block_on(async { let srv = rt.block_on(async {
test::start(|| { actix_test::start(|| {
App::new() App::new()
.service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR)))) .service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
}) })

View File

@ -103,8 +103,8 @@ impl AppService {
} }
} }
/// Application connection config /// Application connection config.
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct AppConfig { pub struct AppConfig {
secure: bool, secure: bool,
host: String, host: String,

View File

@ -148,12 +148,13 @@ impl<T: ?Sized + 'static> DataFactory for Data<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_service::Service; use actix_service::Service;
use std::sync::atomic::{AtomicUsize, Ordering};
use super::*; use super::*;
use crate::http::StatusCode; use crate::{
use crate::test::{self, init_service, TestRequest}; http::StatusCode,
use crate::{web, App, HttpResponse}; test::{init_service, TestRequest},
web, App, HttpResponse,
};
#[actix_rt::test] #[actix_rt::test]
async fn test_data_extractor() { async fn test_data_extractor() {
@ -269,49 +270,6 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
} }
#[actix_rt::test]
async fn test_data_drop() {
struct TestData(Arc<AtomicUsize>);
impl TestData {
fn new(inner: Arc<AtomicUsize>) -> Self {
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Clone for TestData {
fn clone(&self) -> Self {
let inner = self.0.clone();
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Drop for TestData {
fn drop(&mut self) {
let _ = self.0.fetch_sub(1, Ordering::SeqCst);
}
}
let num = Arc::new(AtomicUsize::new(0));
let data = TestData::new(num.clone());
assert_eq!(num.load(Ordering::SeqCst), 1);
let srv = test::start(move || {
let data = data.clone();
App::new()
.data(data)
.service(web::resource("/").to(|_data: Data<TestData>| async { "ok" }))
});
assert!(srv.get("/").send().await.unwrap().status().is_success());
srv.stop().await;
assert_eq!(num.load(Ordering::SeqCst), 0);
}
#[actix_rt::test] #[actix_rt::test]
async fn test_data_from_arc() { async fn test_data_from_arc() {
let data_new = Data::new(String::from("test-123")); let data_new = Data::new(String::from("test-123"));

View File

@ -71,11 +71,6 @@
#![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
#[cfg(feature = "openssl")]
extern crate tls_openssl as openssl;
#[cfg(feature = "rustls")]
extern crate tls_rustls as rustls;
mod app; mod app;
mod app_service; mod app_service;
mod config; mod config;

View File

@ -343,7 +343,7 @@ where
}; };
svc.finish(map_config(factory(), move |_| { svc.finish(map_config(factory(), move |_| {
AppConfig::new(true, addr, host.clone()) AppConfig::new(true, host.clone(), addr)
})) }))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
})?; })?;
@ -396,7 +396,7 @@ where
}; };
svc.finish(map_config(factory(), move |_| { svc.finish(map_config(factory(), move |_| {
AppConfig::new(true, addr, host.clone()) AppConfig::new(true, host.clone(), addr)
})) }))
.rustls(config.clone()) .rustls(config.clone())
})?; })?;

View File

@ -30,13 +30,13 @@ use crate::{
Error, HttpRequest, HttpResponse, Error, HttpRequest, HttpResponse,
}; };
/// Create service that always responds with `HttpResponse::Ok()` /// Create service that always responds with `HttpResponse::Ok()` and no body.
pub fn ok_service( pub fn ok_service(
) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> { ) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> {
default_service(StatusCode::OK) default_service(StatusCode::OK)
} }
/// Create service that responds with response with specified status code /// Create service that always responds with given status code and no body.
pub fn default_service( pub fn default_service(
status_code: StatusCode, status_code: StatusCode,
) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> { ) -> impl Service<ServiceRequest, Response = ServiceResponse<Body>, Error = Error> {
@ -46,8 +46,7 @@ pub fn default_service(
.into_service() .into_service()
} }
/// This method accepts application builder instance, and constructs /// Initialize service from application builder instance.
/// service.
/// ///
/// ``` /// ```
/// use actix_service::Service; /// use actix_service::Service;
@ -81,7 +80,7 @@ where
.expect("service initialization failed") .expect("service initialization failed")
} }
/// Fallible version of init_service that allows testing data factory errors. /// Fallible version of [`init_service`] that allows testing initialization errors.
pub(crate) async fn try_init_service<R, S, B, E>( pub(crate) async fn try_init_service<R, S, B, E>(
app: R, app: R,
) -> Result<impl Service<Request, Response = ServiceResponse<B>, Error = E>, S::InitError> ) -> Result<impl Service<Request, Response = ServiceResponse<B>, Error = E>, S::InitError>

View File

@ -3,14 +3,14 @@ extern crate tls_openssl as openssl;
#[cfg(any(unix, feature = "openssl"))] #[cfg(any(unix, feature = "openssl"))]
use { use {
actix_web::{test, web, App, HttpResponse, HttpServer}, actix_web::{web, App, HttpResponse, HttpServer},
std::{sync::mpsc, thread, time::Duration}, std::{sync::mpsc, thread, time::Duration},
}; };
#[cfg(unix)] #[cfg(unix)]
#[actix_rt::test] #[actix_rt::test]
async fn test_start() { async fn test_start() {
let addr = test::unused_addr(); let addr = actix_test::unused_addr();
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
thread::spawn(move || { thread::spawn(move || {
@ -93,7 +93,7 @@ fn ssl_acceptor() -> openssl::ssl::SslAcceptorBuilder {
async fn test_start_ssl() { async fn test_start_ssl() {
use actix_web::HttpRequest; use actix_web::HttpRequest;
let addr = test::unused_addr(); let addr = actix_test::unused_addr();
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
thread::spawn(move || { thread::spawn(move || {

View File

@ -31,7 +31,7 @@ use rand::{distributions::Alphanumeric, Rng};
use actix_web::dev::BodyEncoding; use actix_web::dev::BodyEncoding;
use actix_web::middleware::{Compress, NormalizePath, TrailingSlash}; use actix_web::middleware::{Compress, NormalizePath, TrailingSlash};
use actix_web::{dev, test, web, App, Error, HttpResponse}; use actix_web::{dev, web, App, Error, HttpResponse};
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \
@ -115,7 +115,7 @@ impl futures_core::stream::Stream for TestBody {
#[actix_rt::test] #[actix_rt::test]
async fn test_body() { async fn test_body() {
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR)))) App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
}); });
@ -129,7 +129,7 @@ async fn test_body() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_gzip() { async fn test_body_gzip() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR)))) .service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
@ -156,7 +156,7 @@ async fn test_body_gzip() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_gzip2() { async fn test_body_gzip2() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| { .service(web::resource("/").route(web::to(|| {
@ -185,7 +185,7 @@ async fn test_body_gzip2() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_encoding_override() { async fn test_body_encoding_override() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| { .service(web::resource("/").route(web::to(|| {
@ -248,7 +248,7 @@ async fn test_body_gzip_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let srv_data = data.clone(); let srv_data = data.clone();
let srv = test::start_with(test::config().h1(), move || { let srv = actix_test::start_with(actix_test::config().h1(), move || {
let data = srv_data.clone(); let data = srv_data.clone();
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
@ -286,7 +286,7 @@ async fn test_body_gzip_large_random() {
.collect::<String>(); .collect::<String>();
let srv_data = data.clone(); let srv_data = data.clone();
let srv = test::start_with(test::config().h1(), move || { let srv = actix_test::start_with(actix_test::config().h1(), move || {
let data = srv_data.clone(); let data = srv_data.clone();
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
@ -318,7 +318,7 @@ async fn test_body_gzip_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_chunked_implicit() { async fn test_body_chunked_implicit() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::get().to(move || { .service(web::resource("/").route(web::get().to(move || {
@ -352,7 +352,7 @@ async fn test_body_chunked_implicit() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_br_streaming() { async fn test_body_br_streaming() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Br)) .wrap(Compress::new(ContentEncoding::Br))
.service(web::resource("/").route(web::to(move || { .service(web::resource("/").route(web::to(move || {
@ -384,7 +384,7 @@ async fn test_body_br_streaming() {
#[actix_rt::test] #[actix_rt::test]
async fn test_head_binary() { async fn test_head_binary() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::head().to(move || HttpResponse::Ok().body(STR))), web::resource("/").route(web::head().to(move || HttpResponse::Ok().body(STR))),
) )
@ -405,7 +405,7 @@ async fn test_head_binary() {
#[actix_rt::test] #[actix_rt::test]
async fn test_no_chunking() { async fn test_no_chunking() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service(web::resource("/").route(web::to(move || { App::new().service(web::resource("/").route(web::to(move || {
HttpResponse::Ok() HttpResponse::Ok()
.no_chunking(STR.len() as u64) .no_chunking(STR.len() as u64)
@ -424,7 +424,7 @@ async fn test_no_chunking() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_deflate() { async fn test_body_deflate() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Deflate)) .wrap(Compress::new(ContentEncoding::Deflate))
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR)))) .service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR))))
@ -451,7 +451,7 @@ async fn test_body_deflate() {
#[actix_rt::test] #[actix_rt::test]
async fn test_body_brotli() { async fn test_body_brotli() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(Compress::new(ContentEncoding::Br)) .wrap(Compress::new(ContentEncoding::Br))
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR)))) .service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR))))
@ -479,7 +479,7 @@ async fn test_body_brotli() {
#[actix_rt::test] #[actix_rt::test]
async fn test_encoding() { async fn test_encoding() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().wrap(Compress::default()).service( App::new().wrap(Compress::default()).service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -504,7 +504,7 @@ async fn test_encoding() {
#[actix_rt::test] #[actix_rt::test]
async fn test_gzip_encoding() { async fn test_gzip_encoding() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -530,7 +530,7 @@ async fn test_gzip_encoding() {
#[actix_rt::test] #[actix_rt::test]
async fn test_gzip_encoding_large() { async fn test_gzip_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -561,7 +561,7 @@ async fn test_reading_gzip_encoding_large_random() {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -587,7 +587,7 @@ async fn test_reading_gzip_encoding_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_reading_deflate_encoding() { async fn test_reading_deflate_encoding() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -613,7 +613,7 @@ async fn test_reading_deflate_encoding() {
#[actix_rt::test] #[actix_rt::test]
async fn test_reading_deflate_encoding_large() { async fn test_reading_deflate_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -644,7 +644,7 @@ async fn test_reading_deflate_encoding_large_random() {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -670,7 +670,7 @@ async fn test_reading_deflate_encoding_large_random() {
#[actix_rt::test] #[actix_rt::test]
async fn test_brotli_encoding() { async fn test_brotli_encoding() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))), web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
) )
@ -701,7 +701,7 @@ async fn test_brotli_encoding_large() {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service( App::new().service(
web::resource("/") web::resource("/")
.app_data(web::PayloadConfig::new(320_000)) .app_data(web::PayloadConfig::new(320_000))
@ -732,13 +732,14 @@ async fn test_brotli_encoding_large() {
#[actix_rt::test] #[actix_rt::test]
async fn test_brotli_encoding_large_openssl() { async fn test_brotli_encoding_large_openssl() {
let data = STR.repeat(10); let data = STR.repeat(10);
let srv = test::start_with(test::config().openssl(openssl_config()), move || { let srv =
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| { actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
HttpResponse::Ok() App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
.encoding(actix_web::http::ContentEncoding::Identity) HttpResponse::Ok()
.body(bytes) .encoding(actix_web::http::ContentEncoding::Identity)
}))) .body(bytes)
}); })))
});
// body // body
let mut e = BrotliEncoder::new(Vec::new(), 3); let mut e = BrotliEncoder::new(Vec::new(), 3);
@ -794,7 +795,7 @@ mod plus_rustls {
.map(char::from) .map(char::from)
.collect::<String>(); .collect::<String>();
let srv = test::start_with(test::config().rustls(rustls_config()), || { let srv = actix_test::start_with(actix_test::config().rustls(rustls_config()), || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| { App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok() HttpResponse::Ok()
.encoding(actix_web::http::ContentEncoding::Identity) .encoding(actix_web::http::ContentEncoding::Identity)
@ -827,7 +828,7 @@ mod plus_rustls {
async fn test_server_cookies() { async fn test_server_cookies() {
use actix_web::{http, HttpMessage}; use actix_web::{http, HttpMessage};
let srv = test::start(|| { let srv = actix_test::start(|| {
App::new().default_service(web::to(|| { App::new().default_service(web::to(|| {
HttpResponse::Ok() HttpResponse::Ok()
.cookie( .cookie(
@ -880,7 +881,7 @@ async fn test_server_cookies() {
async fn test_slow_request() { async fn test_slow_request() {
use std::net; use std::net;
let srv = test::start_with(test::config().client_timeout(200), || { let srv = actix_test::start_with(actix_test::config().client_timeout(200), || {
App::new().service(web::resource("/").route(web::to(HttpResponse::Ok))) App::new().service(web::resource("/").route(web::to(HttpResponse::Ok)))
}); });
@ -898,7 +899,7 @@ async fn test_slow_request() {
#[actix_rt::test] #[actix_rt::test]
async fn test_normalize() { async fn test_normalize() {
let srv = test::start_with(test::config().h1(), || { let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new() App::new()
.wrap(NormalizePath::new(TrailingSlash::Trim)) .wrap(NormalizePath::new(TrailingSlash::Trim))
.service(web::resource("/one").route(web::to(|| HttpResponse::Ok().finish()))) .service(web::resource("/one").route(web::to(|| HttpResponse::Ok().finish())))
@ -907,3 +908,51 @@ async fn test_normalize() {
let response = srv.get("/one/").send().await.unwrap(); let response = srv.get("/one/").send().await.unwrap();
assert!(response.status().is_success()); assert!(response.status().is_success());
} }
#[actix_rt::test]
async fn test_data_drop() {
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
struct TestData(Arc<AtomicUsize>);
impl TestData {
fn new(inner: Arc<AtomicUsize>) -> Self {
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Clone for TestData {
fn clone(&self) -> Self {
let inner = self.0.clone();
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Drop for TestData {
fn drop(&mut self) {
self.0.fetch_sub(1, Ordering::SeqCst);
}
}
let num = Arc::new(AtomicUsize::new(0));
let data = TestData::new(num.clone());
assert_eq!(num.load(Ordering::SeqCst), 1);
let srv = actix_test::start(move || {
let data = data.clone();
App::new()
.data(data)
.service(web::resource("/").to(|_data: web::Data<TestData>| async { "ok" }))
});
assert!(srv.get("/").send().await.unwrap().status().is_success());
srv.stop().await;
assert_eq!(num.load(Ordering::SeqCst), 0);
}