aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/archive.rs58
-rw-r--r--tests/auth.rs140
-rw-r--r--tests/data/cert.pem29
-rwxr-xr-xtests/data/generate_tls_certs.sh2
-rw-r--r--tests/data/key.pem52
-rw-r--r--tests/fixtures/mod.rs116
-rw-r--r--tests/header.rs24
-rw-r--r--tests/navigation.rs103
-rw-r--r--tests/qrcode.rs59
-rw-r--r--tests/serve_request.rs114
-rw-r--r--tests/tls.rs53
-rw-r--r--tests/upload_files.rs48
12 files changed, 355 insertions, 443 deletions
diff --git a/tests/archive.rs b/tests/archive.rs
index 6a7f8bf..b8def22 100644
--- a/tests/archive.rs
+++ b/tests/archive.rs
@@ -1,30 +1,15 @@
mod fixtures;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error};
+use fixtures::{server, Error, TestServer};
use reqwest::StatusCode;
use rstest::rstest;
use select::document::Document;
use select::predicate::Text;
-use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
#[rstest]
-fn archives_are_disabled(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn archives_are_disabled(server: TestServer) -> Result<(), Error> {
// Ensure the links to the archives are not present
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed
.find(Text)
@@ -32,63 +17,42 @@ fn archives_are_disabled(tmpdir: TempDir, port: u16) -> Result<(), Error> {
// Try to download anyway, ensure it's forbidden
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=tar_gz", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=tar_gz")?)?.status(),
StatusCode::FORBIDDEN
);
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=tar", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=tar")?)?.status(),
StatusCode::FORBIDDEN
);
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=zip", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=zip")?)?.status(),
StatusCode::FORBIDDEN
);
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn test_tar_archives(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("-g")
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn test_tar_archives(#[with(&["-g"])] server: TestServer) -> Result<(), Error> {
// Ensure the links to the tar archive exists and tar not exists
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Text).any(|x| x.text() == "Download .tar.gz"));
assert!(parsed.find(Text).all(|x| x.text() != "Download .tar"));
// Try to download, only tar_gz should works
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=tar_gz", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=tar_gz")?)?.status(),
StatusCode::OK
);
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=tar", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=tar")?)?.status(),
StatusCode::FORBIDDEN
);
assert_eq!(
- reqwest::blocking::get(format!("http://localhost:{}/?download=zip", port).as_str())?
- .status(),
+ reqwest::blocking::get(server.url().join("?download=zip")?)?.status(),
StatusCode::FORBIDDEN
);
- child.kill()?;
-
Ok(())
}
diff --git a/tests/auth.rs b/tests/auth.rs
index 09ea8d8..920f738 100644
--- a/tests/auth.rs
+++ b/tests/auth.rs
@@ -1,17 +1,12 @@
mod fixtures;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error, FILES};
+use fixtures::{server, server_no_stderr, Error, FILES};
use pretty_assertions::assert_eq;
use reqwest::blocking::Client;
use reqwest::StatusCode;
use rstest::rstest;
use select::document::Document;
use select::predicate::Text;
-use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
#[rstest(
cli_auth_arg, client_username, client_password,
@@ -28,26 +23,14 @@ use std::time::Duration;
),
)]
fn auth_accepts(
- tmpdir: TempDir,
- port: u16,
cli_auth_arg: &str,
client_username: &str,
client_password: &str,
) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("-a")
- .arg(cli_auth_arg)
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+ let server = server(&["-a", cli_auth_arg]);
let client = Client::new();
let response = client
- .get(format!("http://localhost:{}", port).as_str())
+ .get(server.url())
.basic_auth(client_username, Some(client_password))
.send()?;
@@ -60,8 +43,6 @@ fn auth_accepts(
assert!(parsed.find(Text).any(|x| x.text() == file));
}
- child.kill()?;
-
Ok(())
}
@@ -91,56 +72,39 @@ fn auth_accepts(
),
)]
fn auth_rejects(
- tmpdir: TempDir,
- port: u16,
cli_auth_arg: &str,
client_username: &str,
client_password: &str,
) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("-a")
- .arg(cli_auth_arg)
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+ let server = server_no_stderr(&["-a", cli_auth_arg]);
let client = Client::new();
let status = client
- .get(format!("http://localhost:{}", port).as_str())
+ .get(server.url())
.basic_auth(client_username, Some(client_password))
.send()?
.status();
assert_eq!(status, StatusCode::UNAUTHORIZED);
- child.kill()?;
-
Ok(())
}
-/// Helper function that registers multiple accounts
-#[cfg(test)]
-fn register_accounts<'a>(command: &'a mut Command) -> &'a mut Command {
- command
- .arg("--auth")
- .arg("usr0:pwd0")
- .arg("--auth")
- .arg("usr1:pwd1")
- .arg("--auth")
- .arg("usr2:sha256:149d2937d1bce53fa683ae652291bd54cc8754444216a9e278b45776b76375af") // pwd2
- .arg("--auth")
- .arg("usr3:sha256:ffc169417b4146cebe09a3e9ffbca33db82e3e593b4d04c0959a89c05b87e15d") // pwd3
- .arg("--auth")
- .arg("usr4:sha512:68050a967d061ac480b414bc8f9a6d368ad0082203edcd23860e94c36178aad1a038e061716707d5479e23081a6d920dc6e9f88e5eb789cdd23e211d718d161a") // pwd4
- .arg("--auth")
- .arg("usr5:sha512:be82a7dccd06122f9e232e9730e67e69e30ec61b268fd9b21a5e5d42db770d45586a1ce47816649a0107e9fadf079d9cf0104f0a3aaa0f67bad80289c3ba25a8")
+/// Command line arguments that register multiple accounts
+static ACCOUNTS: &[&str] = &[
+ "--auth",
+ "usr0:pwd0",
+ "--auth",
+ "usr1:pwd1",
+ "--auth",
+ "usr2:sha256:149d2937d1bce53fa683ae652291bd54cc8754444216a9e278b45776b76375af", // pwd2
+ "--auth",
+ "usr3:sha256:ffc169417b4146cebe09a3e9ffbca33db82e3e593b4d04c0959a89c05b87e15d", // pwd3
+ "--auth",
+ "usr4:sha512:68050a967d061ac480b414bc8f9a6d368ad0082203edcd23860e94c36178aad1a038e061716707d5479e23081a6d920dc6e9f88e5eb789cdd23e211d718d161a", // pwd4
+ "--auth",
+ "usr5:sha512:be82a7dccd06122f9e232e9730e67e69e30ec61b268fd9b21a5e5d42db770d45586a1ce47816649a0107e9fadf079d9cf0104f0a3aaa0f67bad80289c3ba25a8",
// pwd5
-}
+];
#[rstest(
username,
@@ -152,25 +116,12 @@ fn register_accounts<'a>(command: &'a mut Command) -> &'a mut Command {
case("usr4", "pwd4"),
case("usr5", "pwd5")
)]
-fn auth_multiple_accounts_pass(
- tmpdir: TempDir,
- port: u16,
- username: &str,
- password: &str,
-) -> Result<(), Error> {
- let mut child = register_accounts(&mut Command::cargo_bin("miniserve")?)
- .arg("-p")
- .arg(port.to_string())
- .arg(tmpdir.path())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn auth_multiple_accounts_pass(username: &str, password: &str) -> Result<(), Error> {
+ let server = server(ACCOUNTS);
let client = Client::new();
let response = client
- .get(format!("http://localhost:{}", port).as_str())
+ .get(server.url())
.basic_auth(username, Some(password))
.send()?;
@@ -183,37 +134,22 @@ fn auth_multiple_accounts_pass(
assert!(parsed.find(Text).any(|x| x.text() == file));
}
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn auth_multiple_accounts_wrong_username(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = register_accounts(
- Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .stderr(Stdio::null()),
- )
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn auth_multiple_accounts_wrong_username() -> Result<(), Error> {
+ let server = server_no_stderr(ACCOUNTS);
let client = Client::new();
let status = client
- .get(format!("http://localhost:{}", port).as_str())
+ .get(server.url())
.basic_auth("unregistered user", Some("pwd0"))
.send()?
.status();
assert_eq!(status, StatusCode::UNAUTHORIZED);
- child.kill()?;
-
Ok(())
}
@@ -227,35 +163,17 @@ fn auth_multiple_accounts_wrong_username(tmpdir: TempDir, port: u16) -> Result<(
case("usr4", "pwd1"),
case("usr5", "pwd0")
)]
-fn auth_multiple_accounts_wrong_password(
- tmpdir: TempDir,
- port: u16,
- username: &str,
- password: &str,
-) -> Result<(), Error> {
- let mut child = register_accounts(
- Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .stderr(Stdio::null()),
- )
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn auth_multiple_accounts_wrong_password(username: &str, password: &str) -> Result<(), Error> {
+ let server = server_no_stderr(ACCOUNTS);
let client = Client::new();
let status = client
- .get(format!("http://localhost:{}", port).as_str())
+ .get(server.url())
.basic_auth(username, Some(password))
.send()?
.status();
assert_eq!(status, StatusCode::UNAUTHORIZED);
- child.kill()?;
-
Ok(())
}
diff --git a/tests/data/cert.pem b/tests/data/cert.pem
new file mode 100644
index 0000000..c907ef2
--- /dev/null
+++ b/tests/data/cert.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIFCTCCAvGgAwIBAgIUJUf2QS/pOdHEW4EHTfdXxeTvtM8wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIxMDgyNzAwMzEyOFoXDTMxMDgy
+NTAwMzEyOFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEAwmYOqToI0R30lPyYtF9bSuhIOCp9cp0jl2nuHaO8mpr1
+gMiJKKN4HjAdgac+3hYkTRFqK2mKKpV9QdVKR24Ib7mC45Ek7BlLw3VbxPRKrK/j
+rKW3M3ui+453B24yf6K8dH36x9gZo4glzghFxuodFakIX2zNKo6tEx0XVkbhsu/w
+vj2s+0L3oToPAYZaiOB/7xYU6Yu9n7Tn6rE9/orDfK1DlrZDP3hzyxLzuf6tqXCh
+66cgaPQTh+xyyWZcvl60kbB4H3bdhqbYGMMQO8bUxXTQXjwvUsvl0yn9qCpMIn99
+Pm9xhfDQSF3zawM3CQ/lmn9uFQzdOEfYlO6oaidTqxLtBhVUcEutIcmoW9nmmv2g
+Ei49/3OmvWQcEdMWt8xwxSrMvKDSeUdF3rbalTHBFQHJlJiKRX9wTNtSZ5T8FTU7
+4Ip4EzAtP8wY5NDv253mddANoyKsVRGytS35LDFkCS/TxuVDZrjluc86yqUId/jf
+HZAzQ7ifpC890aG0JOq/0mmVDvbn7MzdTsTWwhE8UaOiFljTiNQX3QjX3TaEu32M
+XHKo5nebNqDVRGnFMFmfXw2ZP8lgQCWk1HxLr0qhRxIy8XmIK1ZUz7Uc4Cba73XB
+pSxcIPytpDuuKotslBjoIYu9DY07n1Hu4zYPvpP9DnaunEW6zmANEtjSyrE/TQ0C
+AwEAAaNTMFEwHQYDVR0OBBYEFH0VzGnFqGVB+11uyvqea2qXYxQKMB8GA1UdIwQY
+MBaAFH0VzGnFqGVB+11uyvqea2qXYxQKMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggIBAA4FqzX34FCU1WYzmBRcq7QHSrc7LcuTbxhESB7mYbI8IPFt
+cgrtXL1mTP+nz5nN+E6fyA8Y9zIyXm/6svYpJzXgUTtbdgDW22v5iN+YZvOaQ3Jt
+/0eEtkx7wdNjLsN0aM6OjPXDw0mAVFDdevE7wgnra6x6/VHOt6pksNJa76ZVPX5X
+dlLj+OU4eQPPMVxhL7p3xdSPFDZzXY7mNfVycO3tK5Fzrwko7OQKqEBMtc0oZxLd
+m/FvqcJveHYHfXZl5XKMcsCNO8bG0XXDhwg0CLTf1p0hmp1oLieqplekOWs54Alo
+FF4EBNdDaIFdQ4FAYaAU+9KLoPstorTl+3Owj/k3xhDB+0sGwGeX/e88nhs/ppEy
+bxOt0j4AruwapkcvkwhQeMpQJRYyOrcvlbUEZqFABozZ9gbGRQvnConDNg7tz5zc
+nVUupszA7zs0Vn9b1zVLOcOcS2ziQvoCyh687MsVbjw65Y6tkhvLI35G68zrFKsl
+MS5mqnK4DZYFc1gGGI/rjsFUf3dD4ww6PTnwv3Ga2yBvXi7EckEeEqB+dRlVdvob
+cH/grVUum3s5Y4PTnxyNAUFZlFNZ8jlOcgXtAFuTnJ/jcvboZdE7Oja2OIMJo53d
+rbkqAPNGhQ98QDuTwWjHUq/Th1CQK4ALI/wqoc22TJpSh/mme5Dj4HhB7LWl
+-----END CERTIFICATE-----
diff --git a/tests/data/generate_tls_certs.sh b/tests/data/generate_tls_certs.sh
new file mode 100755
index 0000000..969a38c
--- /dev/null
+++ b/tests/data/generate_tls_certs.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+openssl req -subj '/CN=localhost' -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 3650
diff --git a/tests/data/key.pem b/tests/data/key.pem
new file mode 100644
index 0000000..4263815
--- /dev/null
+++ b/tests/data/key.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+UbBWUEN95O4LnWFuyhEIOIEmp5JtGks=
+-----END PRIVATE KEY-----
diff --git a/tests/fixtures/mod.rs b/tests/fixtures/mod.rs
index 1cf6c59..ec17f3e 100644
--- a/tests/fixtures/mod.rs
+++ b/tests/fixtures/mod.rs
@@ -1,7 +1,12 @@
+use assert_cmd::prelude::*;
use assert_fs::fixture::TempDir;
use assert_fs::prelude::*;
use port_check::free_local_port;
+use reqwest::Url;
use rstest::fixture;
+use std::process::{Child, Command, Stdio};
+use std::thread::sleep;
+use std::time::{Duration, Instant};
/// Error type used by tests
pub type Error = Box<dyn std::error::Error>;
@@ -19,6 +24,8 @@ pub static FILES: &[&str] = &[
"#[]{}()@!$&'`+,;= %20.test",
#[cfg(unix)]
":?#[]{}<>()@!$&'`|*+,;= %20.test",
+ #[cfg(not(windows))]
+ "foo\\bar.test",
];
/// Hidden files for testing purpose
@@ -76,3 +83,112 @@ pub fn tmpdir() -> TempDir {
pub fn port() -> u16 {
free_local_port().expect("Couldn't find a free local port")
}
+
+/// Run miniserve as a server; Start with a temporary directory, a free port and some
+/// optional arguments then wait for a while for the server setup to complete.
+#[fixture]
+#[allow(dead_code)]
+pub fn server<I>(#[default(&[] as &[&str])] args: I) -> TestServer
+where
+ I: IntoIterator + Clone,
+ I::Item: AsRef<std::ffi::OsStr>,
+{
+ let port = port();
+ let tmpdir = tmpdir();
+ let child = Command::cargo_bin("miniserve")
+ .expect("Couldn't find test binary")
+ .arg(tmpdir.path())
+ .arg("-p")
+ .arg(port.to_string())
+ .args(args.clone())
+ .stdout(Stdio::null())
+ .spawn()
+ .expect("Couldn't run test binary");
+ let is_tls = args
+ .into_iter()
+ .any(|x| x.as_ref().to_str().unwrap().contains("tls"));
+
+ wait_for_port(port);
+ TestServer::new(port, tmpdir, child, is_tls)
+}
+
+/// Same as `server()` but ignore stderr
+#[fixture]
+#[allow(dead_code)]
+pub fn server_no_stderr<I>(#[default(&[] as &[&str])] args: I) -> TestServer
+where
+ I: IntoIterator + Clone,
+ I::Item: AsRef<std::ffi::OsStr>,
+{
+ let port = port();
+ let tmpdir = tmpdir();
+ let child = Command::cargo_bin("miniserve")
+ .expect("Couldn't find test binary")
+ .arg(tmpdir.path())
+ .arg("-p")
+ .arg(port.to_string())
+ .args(args.clone())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()
+ .expect("Couldn't run test binary");
+ let is_tls = args
+ .into_iter()
+ .any(|x| x.as_ref().to_str().unwrap().contains("tls"));
+
+ wait_for_port(port);
+ TestServer::new(port, tmpdir, child, is_tls)
+}
+
+/// Wait a max of 1s for the port to become available.
+fn wait_for_port(port: u16) {
+ let start_wait = Instant::now();
+
+ while !port_check::is_port_reachable(format!("localhost:{}", port)) {
+ sleep(Duration::from_millis(100));
+
+ if start_wait.elapsed().as_secs() > 1 {
+ panic!("timeout waiting for port {}", port);
+ }
+ }
+}
+
+#[allow(dead_code)]
+pub struct TestServer {
+ port: u16,
+ tmpdir: TempDir,
+ child: Child,
+ is_tls: bool,
+}
+
+#[allow(dead_code)]
+impl TestServer {
+ pub fn new(port: u16, tmpdir: TempDir, child: Child, is_tls: bool) -> Self {
+ Self {
+ port,
+ tmpdir,
+ child,
+ is_tls,
+ }
+ }
+
+ pub fn url(&self) -> Url {
+ let protocol = if self.is_tls { "https" } else { "http" };
+ Url::parse(&format!("{}://localhost:{}", protocol, self.port)).unwrap()
+ }
+
+ pub fn path(&self) -> &std::path::Path {
+ self.tmpdir.path()
+ }
+
+ pub fn port(&self) -> u16 {
+ self.port
+ }
+}
+
+impl Drop for TestServer {
+ fn drop(&mut self) {
+ self.child.kill().expect("Couldn't kill test server");
+ self.child.wait().unwrap();
+ }
+}
diff --git a/tests/header.rs b/tests/header.rs
index e46044c..4ac38b1 100644
--- a/tests/header.rs
+++ b/tests/header.rs
@@ -1,29 +1,15 @@
mod fixtures;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error};
+use fixtures::{server, Error};
use rstest::rstest;
-use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
#[rstest(headers,
case(vec!["x-info: 123".to_string()]),
case(vec!["x-info1: 123".to_string(), "x-info2: 345".to_string()])
)]
-fn custom_header_set(tmpdir: TempDir, port: u16, headers: Vec<String>) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .args(headers.iter().flat_map(|h| vec!["--header", h]))
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let resp = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?;
+fn custom_header_set(headers: Vec<String>) -> Result<(), Error> {
+ let server = server(headers.iter().flat_map(|h| vec!["--header", h]));
+ let resp = reqwest::blocking::get(server.url())?;
for header in headers {
let mut header_split = header.splitn(2, ':');
@@ -32,7 +18,5 @@ fn custom_header_set(tmpdir: TempDir, port: u16, headers: Vec<String>) -> Result
assert_eq!(resp.headers().get(header_name).unwrap(), header_value);
}
- child.kill()?;
-
Ok(())
}
diff --git a/tests/navigation.rs b/tests/navigation.rs
index c5c18cb..f4a2e1f 100644
--- a/tests/navigation.rs
+++ b/tests/navigation.rs
@@ -1,16 +1,11 @@
mod fixtures;
mod utils;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error, DEEPLY_NESTED_FILE, DIRECTORIES};
+use fixtures::{server, Error, TestServer, DEEPLY_NESTED_FILE, DIRECTORIES};
use pretty_assertions::{assert_eq, assert_ne};
use rstest::rstest;
use select::document::Document;
use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
-use url::Url;
use utils::get_link_from_text;
#[rstest(
@@ -22,45 +17,19 @@ use utils::get_link_from_text;
case("/very/deeply/nested", "/very/deeply/nested/")
)]
/// Directories get a trailing slash.
-fn index_gets_trailing_slash(
- tmpdir: TempDir,
- port: u16,
- input: &str,
- expected: &str,
-) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg("-p")
- .arg(port.to_string())
- .arg(tmpdir.path())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let base_url = Url::parse(&format!("http://localhost:{}", port))?;
- let resp = reqwest::blocking::get(base_url.join(input)?)?;
+fn index_gets_trailing_slash(server: TestServer, input: &str, expected: &str) -> Result<(), Error> {
+ let resp = reqwest::blocking::get(server.url().join(input)?)?;
assert!(resp.url().as_str().ends_with(expected));
- child.kill()?;
-
Ok(())
}
#[rstest]
/// Can't navigate up the root.
-fn cant_navigate_up_the_root(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg("-p")
- .arg(port.to_string())
- .arg(tmpdir.path())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn cant_navigate_up_the_root(server: TestServer) -> Result<(), Error> {
// We're using curl for this as it has the option `--path-as-is` which doesn't normalize
// invalid urls. A useful feature in this particular case.
- let base_url = Url::parse(&format!("http://localhost:{}", port))?;
+ let base_url = server.url();
let curl_successful = Command::new("curl")
.arg("-s")
.arg("--fail")
@@ -71,24 +40,13 @@ fn cant_navigate_up_the_root(tmpdir: TempDir, port: u16) -> Result<(), Error> {
.success();
assert!(curl_successful);
- child.kill()?;
-
Ok(())
}
#[rstest]
/// We can navigate into directories and back using shown links.
-fn can_navigate_into_dirs_and_back(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg("-p")
- .arg(port.to_string())
- .arg(tmpdir.path())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let base_url = Url::parse(&format!("http://localhost:{}/", port))?;
+fn can_navigate_into_dirs_and_back(server: TestServer) -> Result<(), Error> {
+ let base_url = server.url();
let initial_body = reqwest::blocking::get(base_url.as_str())?.error_for_status()?;
let initial_parsed = Document::from_read(initial_body)?;
for &directory in DIRECTORIES {
@@ -105,23 +63,12 @@ fn can_navigate_into_dirs_and_back(tmpdir: TempDir, port: u16) -> Result<(), Err
assert_eq!(resp.url().as_str(), base_url.as_str());
}
- child.kill()?;
-
Ok(())
}
#[rstest]
/// We can navigate deep into the file tree and back using shown links.
-fn can_navigate_deep_into_dirs_and_back(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg("-p")
- .arg(port.to_string())
- .arg(tmpdir.path())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn can_navigate_deep_into_dirs_and_back(server: TestServer) -> Result<(), Error> {
// Create a vector of directory names. We don't need to fetch the file and so we'll
// remove that part.
let dir_names = {
@@ -132,7 +79,7 @@ fn can_navigate_deep_into_dirs_and_back(tmpdir: TempDir, port: u16) -> Result<()
comps.pop();
comps
};
- let base_url = Url::parse(&format!("http://localhost:{}/", port))?;
+ let base_url = server.url();
// First we'll go forwards through the directory tree and then we'll go backwards.
// In the end, we'll have to end up where we came from.
@@ -157,29 +104,17 @@ fn can_navigate_deep_into_dirs_and_back(tmpdir: TempDir, port: u16) -> Result<()
}
assert_eq!(base_url, next_url);
- child.kill()?;
-
Ok(())
}
-#[rstest(use_custom_title, case(true), case(false))]
+#[rstest]
+#[case(server(&["--title", "some title"]), "some title")]
+#[case(server(None::<&str>), format!("localhost:{}", server.port()))]
/// We can use breadcrumbs to navigate.
fn can_navigate_using_breadcrumbs(
- tmpdir: TempDir,
- port: u16,
- use_custom_title: bool,
+ #[case] server: TestServer,
+ #[case] title_name: String,
) -> Result<(), Error> {
- let mut command_base = Command::cargo_bin("miniserve")?;
- let mut command = command_base.arg("-p").arg(port.to_string());
-
- if use_custom_title {
- command = command.arg("--title").arg("some title")
- }
-
- let mut child = command.arg(tmpdir.path()).stdout(Stdio::null()).spawn()?;
-
- sleep(Duration::from_secs(1));
-
// Create a vector of directory names. We don't need to fetch the file and so we'll
// remove that part.
let dir: String = {
@@ -191,19 +126,13 @@ fn can_navigate_using_breadcrumbs(
comps.join("")
};
- let base_url = Url::parse(&format!("http://localhost:{}/", port))?;
+ let base_url = server.url();
let nested_url = base_url.join(&dir)?;
let resp = reqwest::blocking::get(nested_url.as_str())?;
let body = resp.error_for_status()?;
let parsed = Document::from_read(body)?;
- let title_name = if use_custom_title {
- "some title".to_string()
- } else {
- format!("localhost:{}", port)
- };
-
// can go back to root dir by clicking title
let title_link = get_link_from_text(&parsed, &title_name).expect("Root dir link not found.");
assert_eq!("/", title_link);
@@ -217,7 +146,5 @@ fn can_navigate_using_breadcrumbs(
let current_dir_link = get_link_from_text(&parsed, "nested");
assert_eq!(None, current_dir_link);
- child.kill()?;
-
Ok(())
}
diff --git a/tests/qrcode.rs b/tests/qrcode.rs
index d9a5529..a9c27fe 100644
--- a/tests/qrcode.rs
+++ b/tests/qrcode.rs
@@ -1,74 +1,34 @@
mod fixtures;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error};
+use fixtures::{server, server_no_stderr, Error, TestServer};
use reqwest::StatusCode;
use rstest::rstest;
use select::document::Document;
use select::predicate::Attr;
use std::iter::repeat_with;
-use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
#[rstest]
-fn hide_qrcode_element(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+fn hide_qrcode_element(server: TestServer) -> Result<(), Error> {
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Attr("id", "qrcode")).next().is_none());
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn show_qrcode_element(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("-q")
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+fn show_qrcode_element(#[with(&["-q"])] server: TestServer) -> Result<(), Error> {
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Attr("id", "qrcode")).next().is_some());
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn get_svg_qrcode(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
+fn get_svg_qrcode(#[from(server_no_stderr)] server: TestServer) -> Result<(), Error> {
// Ok
- let resp = reqwest::blocking::get(format!("http://localhost:{}/?qrcode=test", port).as_str())?;
+ let resp = reqwest::blocking::get(server.url().join("/?qrcode=test")?)?;
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers()["Content-Type"], "image/svg+xml");
@@ -78,12 +38,9 @@ fn get_svg_qrcode(tmpdir: TempDir, port: u16) -> Result<(), Error> {
// Err
let content: String = repeat_with(|| '0').take(8 * 1024).collect();
- let resp =
- reqwest::blocking::get(format!("http://localhost:{}/?qrcode={}", port, content).as_str())?;
+ let resp = reqwest::blocking::get(server.url().join(&format!("?qrcode={}", content))?)?;
assert_eq!(resp.status(), StatusCode::URI_TOO_LONG);
- child.kill()?;
-
Ok(())
}
diff --git a/tests/serve_request.rs b/tests/serve_request.rs
index e259b9e..361801b 100644
--- a/tests/serve_request.rs
+++ b/tests/serve_request.rs
@@ -2,13 +2,14 @@ mod fixtures;
use assert_cmd::prelude::*;
use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error, DIRECTORIES, FILES, HIDDEN_DIRECTORIES, HIDDEN_FILES};
+use fixtures::{
+ port, server, tmpdir, Error, TestServer, DIRECTORIES, FILES, HIDDEN_DIRECTORIES, HIDDEN_FILES,
+};
use http::StatusCode;
use regex::Regex;
use rstest::rstest;
use select::document::Document;
use select::node::Node;
-use std::path::Path;
use std::process::{Command, Stdio};
use std::thread::sleep;
use std::time::Duration;
@@ -39,28 +40,13 @@ fn serves_requests_with_no_options(tmpdir: TempDir) -> Result<(), Error> {
}
#[rstest]
-fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+fn serves_requests_with_non_default_port(server: TestServer) -> Result<(), Error> {
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
for &file in FILES {
let f = parsed.find(|x: &Node| x.text() == file).next().unwrap();
- reqwest::blocking::get(format!(
- "http://localhost:{}/{}",
- port,
- f.attr("href").unwrap()
- ))?
- .error_for_status()?;
+ reqwest::blocking::get(server.url().join(f.attr("href").unwrap())?)?.error_for_status()?;
assert_eq!(
format!("/{}", file),
percent_encoding::percent_decode_str(f.attr("href").unwrap()).decode_utf8_lossy(),
@@ -73,8 +59,7 @@ fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<(
.next()
.is_some());
let dir_body =
- reqwest::blocking::get(format!("http://localhost:{}/{}", port, directory).as_str())?
- .error_for_status()?;
+ reqwest::blocking::get(server.url().join(&directory)?)?.error_for_status()?;
let dir_body_parsed = Document::from_read(dir_body)?;
for &file in FILES {
assert!(dir_body_parsed
@@ -84,25 +69,12 @@ fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<(
}
}
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn serves_requests_hidden_files(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("--hidden")
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+fn serves_requests_hidden_files(#[with(&["--hidden"])] server: TestServer) -> Result<(), Error> {
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
for &file in FILES.into_iter().chain(HIDDEN_FILES) {
@@ -119,8 +91,7 @@ fn serves_requests_hidden_files(tmpdir: TempDir, port: u16) -> Result<(), Error>
.next()
.is_some());
let dir_body =
- reqwest::blocking::get(format!("http://localhost:{}/{}", port, directory).as_str())?
- .error_for_status()?;
+ reqwest::blocking::get(server.url().join(&directory)?)?.error_for_status()?;
let dir_body_parsed = Document::from_read(dir_body)?;
for &file in FILES.into_iter().chain(HIDDEN_FILES) {
assert!(dir_body_parsed
@@ -130,24 +101,12 @@ fn serves_requests_hidden_files(tmpdir: TempDir, port: u16) -> Result<(), Error>
}
}
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn serves_requests_no_hidden_files_without_flag(tmpdir: TempDir, port: u16) -> Result<(), Error> {
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+fn serves_requests_no_hidden_files_without_flag(server: TestServer) -> Result<(), Error> {
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
for &hidden_item in HIDDEN_FILES.into_iter().chain(HIDDEN_DIRECTORIES) {
@@ -155,54 +114,38 @@ fn serves_requests_no_hidden_files_without_flag(tmpdir: TempDir, port: u16) -> R
.find(|x: &Node| x.text() == hidden_item)
.next()
.is_none());
- let resp =
- reqwest::blocking::get(format!("http://localhost:{}/{}", port, hidden_item).as_str())?;
+ let resp = reqwest::blocking::get(server.url().join(&hidden_item)?)?;
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}
- child.kill()?;
-
Ok(())
}
-#[rstest(no_symlinks, case(true), case(false))]
-fn serves_requests_symlinks(tmpdir: TempDir, port: u16, no_symlinks: bool) -> Result<(), Error> {
- let mut comm = Command::cargo_bin("miniserve")?;
- comm.arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null());
- if no_symlinks {
- comm.arg("--no-symlinks");
- }
-
- let mut child = comm.spawn()?;
- sleep(Duration::from_secs(1));
-
+#[rstest]
+#[case(true, server(&["--no-symlinks"]))]
+#[case(false, server(None::<&str>))]
+fn serves_requests_symlinks(
+ #[case] no_symlinks: bool,
+ #[case] server: TestServer,
+) -> Result<(), Error> {
let files = &["symlink-file.html"];
let dirs = &["symlink-dir/"];
let broken = &["symlink broken"];
for &directory in dirs {
- let orig = Path::new(DIRECTORIES[0].strip_suffix("/").unwrap());
- let link = tmpdir
- .path()
- .join(Path::new(directory.strip_suffix("/").unwrap()));
+ let orig = DIRECTORIES[0].strip_suffix("/").unwrap();
+ let link = server.path().join(directory.strip_suffix("/").unwrap());
symlink_dir(orig, link).expect("Couldn't create symlink");
}
for &file in files {
- let orig = Path::new(FILES[0]);
- let link = tmpdir.path().join(Path::new(file));
- symlink_file(orig, link).expect("Couldn't create symlink");
+ symlink_file(FILES[0], server.path().join(file)).expect("Couldn't create symlink");
}
for &file in broken {
- let orig = Path::new("should-not-exist.xxx");
- let link = tmpdir.path().join(Path::new(file));
- symlink_file(orig, link).expect("Couldn't create symlink");
+ symlink_file("should-not-exist.xxx", server.path().join(file))
+ .expect("Couldn't create symlink");
}
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
for &entry in files.into_iter().chain(dirs) {
@@ -216,8 +159,7 @@ fn serves_requests_symlinks(tmpdir: TempDir, port: u16, no_symlinks: bool) -> Re
let node = node.unwrap();
assert_eq!(node.attr("href").unwrap().strip_prefix("/").unwrap(), entry);
- reqwest::blocking::get(format!("http://localhost:{}/{}", port, entry))?
- .error_for_status()?;
+ reqwest::blocking::get(server.url().join(&entry)?)?.error_for_status()?;
if entry.ends_with("/") {
assert_eq!(node.attr("class").unwrap(), "directory");
} else {
@@ -228,8 +170,6 @@ fn serves_requests_symlinks(tmpdir: TempDir, port: u16, no_symlinks: bool) -> Re
assert!(parsed.find(|x: &Node| x.text() == entry).next().is_none());
}
- child.kill()?;
-
Ok(())
}
diff --git a/tests/tls.rs b/tests/tls.rs
new file mode 100644
index 0000000..2464e1f
--- /dev/null
+++ b/tests/tls.rs
@@ -0,0 +1,53 @@
+mod fixtures;
+
+use assert_cmd::Command;
+use fixtures::{server, Error, TestServer, FILES};
+use predicates::str::contains;
+use reqwest::blocking::ClientBuilder;
+use rstest::rstest;
+use select::{document::Document, node::Node};
+
+/// Can start the server with TLS and receive encrypted responses.
+#[rstest]
+fn tls_works(
+ #[with(&[
+ "--tls-cert", "tests/data/cert.pem",
+ "--tls-key", "tests/data/key.pem"
+ ])]
+ server: TestServer,
+) -> Result<(), Error> {
+ let client = ClientBuilder::new()
+ .danger_accept_invalid_certs(true)
+ .build()?;
+ let body = client.get(server.url()).send()?.error_for_status()?;
+ let parsed = Document::from_read(body)?;
+ for &file in FILES {
+ assert!(parsed.find(|x: &Node| x.text() == file).next().is_some());
+ }
+
+ Ok(())
+}
+
+/// Wrong path for cert throws error.
+#[rstest]
+fn wrong_path_cert() -> Result<(), Error> {
+ Command::cargo_bin("miniserve")?
+ .args(&["--tls-cert", "wrong", "--tls-key", "tests/data/key.pem"])
+ .assert()
+ .failure()
+ .stderr(contains("Error: Couldn't access TLS certificate \"wrong\""));
+
+ Ok(())
+}
+
+/// Wrong paths for key throws errors.
+#[rstest]
+fn wrong_path_key() -> Result<(), Error> {
+ Command::cargo_bin("miniserve")?
+ .args(&["--tls-cert", "tests/data/cert.pem", "--tls-key", "wrong"])
+ .assert()
+ .failure()
+ .stderr(contains("Error: Couldn't access TLS key \"wrong\""));
+
+ Ok(())
+}
diff --git a/tests/upload_files.rs b/tests/upload_files.rs
index 58707c5..698eb46 100644
--- a/tests/upload_files.rs
+++ b/tests/upload_files.rs
@@ -1,33 +1,17 @@
mod fixtures;
-use assert_cmd::prelude::*;
-use assert_fs::fixture::TempDir;
-use fixtures::{port, tmpdir, Error};
+use fixtures::{server, Error, TestServer};
use reqwest::blocking::{multipart, Client};
use rstest::rstest;
use select::document::Document;
use select::predicate::{Attr, Text};
-use std::process::{Command, Stdio};
-use std::thread::sleep;
-use std::time::Duration;
#[rstest]
-fn uploading_files_works(tmpdir: TempDir, port: u16) -> Result<(), Error> {
+fn uploading_files_works(#[with(&["-u"])] server: TestServer) -> Result<(), Error> {
let test_file_name = "uploaded test file.txt";
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .arg("-u")
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
// Before uploading, check whether the uploaded file does not yet exist.
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Text).all(|x| x.text() != test_file_name));
@@ -46,37 +30,25 @@ fn uploading_files_works(tmpdir: TempDir, port: u16) -> Result<(), Error> {
let client = Client::new();
client
- .post(format!("http://localhost:{}{}", port, upload_action).as_str())
+ .post(server.url().join(upload_action)?)
.multipart(form)
.send()?
.error_for_status()?;
// After uploading, check whether the uploaded file is now getting listed.
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?;
+ let body = reqwest::blocking::get(server.url())?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Text).any(|x| x.text() == test_file_name));
- child.kill()?;
-
Ok(())
}
#[rstest]
-fn uploading_files_is_prevented(tmpdir: TempDir, port: u16) -> Result<(), Error> {
+fn uploading_files_is_prevented(server: TestServer) -> Result<(), Error> {
let test_file_name = "uploaded test file.txt";
- let mut child = Command::cargo_bin("miniserve")?
- .arg(tmpdir.path())
- .arg("-p")
- .arg(port.to_string())
- .stdout(Stdio::null())
- .spawn()?;
-
- sleep(Duration::from_secs(1));
-
// Before uploading, check whether the uploaded file does not yet exist.
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?
- .error_for_status()?;
+ let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;
assert!(parsed.find(Text).all(|x| x.text() != test_file_name));
@@ -93,18 +65,16 @@ fn uploading_files_is_prevented(tmpdir: TempDir, port: u16) -> Result<(), Error>
let client = Client::new();
// Ensure uploading fails and returns an error
assert!(client
- .post(format!("http://localhost:{}{}", port, "/upload?path=/").as_str())
+ .post(server.url().join("/upload?path=/")?)
.multipart(form)
.send()?
.error_for_status()
.is_err());
// After uploading, check whether the uploaded file is now getting listed.
- let body = reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?;
+ let body = reqwest::blocking::get(server.url())?;
let parsed = Document::from_read(body)?;
assert!(!parsed.find(Text).any(|x| x.text() == test_file_name));
- child.kill()?;
-
Ok(())
}