Skip to content

Commit

Permalink
Add server integration test (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Sep 30, 2022
1 parent f3921c3 commit a1ede2e
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 16 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ tower-http = { version = "0.3.3", features = ["cors"] }

[dev-dependencies]
executable-path = "1.0.0"
nix = "0.25.0"
pretty_assertions = "1.2.1"
reqwest = { version = "0.11.10", features = ["blocking"] }
tempfile = "3.2.0"
Expand Down
46 changes: 34 additions & 12 deletions tests/command_builder.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use super::*;

enum ExpectedExitStatus {
Code(i32),
Signal(Signal),
}

pub(crate) struct CommandBuilder {
args: &'static str,
expected_status: i32,
expected_exit_status: ExpectedExitStatus,
expected_stderr: Expected,
expected_stdout: Expected,
rpc_server_url: Option<String>,
Expand All @@ -13,7 +18,7 @@ impl CommandBuilder {
pub(crate) fn new(args: &'static str) -> Self {
Self {
args,
expected_status: 0,
expected_exit_status: ExpectedExitStatus::Code(0),
expected_stderr: Expected::String(String::new()),
expected_stdout: Expected::String(String::new()),
rpc_server_url: None,
Expand Down Expand Up @@ -56,41 +61,53 @@ impl CommandBuilder {
}
}

pub(crate) fn expected_status(self, expected_status: i32) -> Self {
pub(crate) fn expected_exit_code(self, expected_status: i32) -> Self {
Self {
expected_status,
expected_exit_status: ExpectedExitStatus::Code(expected_status),
..self
}
}

pub(crate) fn run(self) -> TempDir {
pub(crate) fn expected_exit_signal(self, expected_signal: Signal) -> Self {
Self {
expected_exit_status: ExpectedExitStatus::Signal(expected_signal),
..self
}
}

pub(crate) fn command(&self) -> Command {
let mut command = Command::new(executable_path("ord"));

if let Some(rpc_server_url) = self.rpc_server_url {
if let Some(rpc_server_url) = &self.rpc_server_url {
let cookiefile = self.tempdir.path().join("cookie");
fs::write(&cookiefile, "username:password").unwrap();
command.args(&[
"--rpc-url",
&rpc_server_url,
rpc_server_url,
"--cookie-file",
cookiefile.to_str().unwrap(),
]);
}

let output = command
command
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.env("HOME", self.tempdir.path())
.current_dir(&self.tempdir)
.args(self.args.split_whitespace())
.output()
.unwrap();
.args(self.args.split_whitespace());

command
}

pub(crate) fn check(self, output: Output) -> TempDir {
let stdout = str::from_utf8(&output.stdout).unwrap();
let stderr = str::from_utf8(&output.stderr).unwrap();

if output.status.code() != Some(self.expected_status) {
if match self.expected_exit_status {
ExpectedExitStatus::Code(code) => output.status.code() != Some(code),
ExpectedExitStatus::Signal(signal) => output.status.signal() != Some(signal as i32),
} {
panic!(
"Test failed: {}\nstdout:\n{}\nstderr:\n{}",
output.status, stdout, stderr
Expand All @@ -102,4 +119,9 @@ impl CommandBuilder {

self.tempdir
}

pub(crate) fn run(self) -> TempDir {
let output = self.command().output().unwrap();
self.check(output)
}
}
2 changes: 1 addition & 1 deletion tests/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ fn unmined_ordinal() {
CommandBuilder::new("find 5000000000")
.rpc_server(&rpc_server)
.expected_stderr("error: Ordinal has not been mined as of index height\n")
.expected_status(1)
.expected_exit_code(1)
.run();
}
5 changes: 4 additions & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
use {
self::{command_builder::CommandBuilder, expected::Expected},
executable_path::executable_path,
nix::{sys::signal::Signal, unistd::Pid},
regex::Regex,
std::{
fs,
process::{Command, Stdio},
os::unix::process::ExitStatusExt,
process::{Command, Output, Stdio},
str,
},
tempfile::TempDir,
Expand All @@ -22,6 +24,7 @@ mod info;
mod list;
mod parse;
mod range;
mod server;
mod supply;
mod traits;
mod version;
2 changes: 1 addition & 1 deletion tests/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn output_not_found() {
let rpc_server = test_bitcoincore_rpc::spawn();
CommandBuilder::new("list 0000000000000000000000000000000000000000000000000000000000000000:0")
.rpc_server(&rpc_server)
.expected_status(1)
.expected_exit_code(1)
.expected_stderr("error: Output not found\n")
.run();
}
2 changes: 1 addition & 1 deletion tests/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ fn ok() {
fn err() {
CommandBuilder::new("parse A")
.stderr_regex("error: .*: invalid digit found in string.*")
.expected_status(2)
.expected_exit_code(2)
.run();
}
24 changes: 24 additions & 0 deletions tests/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::*;

#[test]
fn run() {
let rpc_server = test_bitcoincore_rpc::spawn();

let builder = CommandBuilder::new("server")
.rpc_server(&rpc_server)
.expected_exit_signal(Signal::SIGINT);

let mut command = builder.command();

let mut child = command.spawn().unwrap();

nix::sys::signal::kill(
Pid::from_raw(child.id().try_into().unwrap()),
Signal::SIGINT,
)
.unwrap();

child.kill().unwrap();

builder.check(child.wait_with_output().unwrap());
}

0 comments on commit a1ede2e

Please sign in to comment.