test(lightwalletd): add a lightwalletd integration test (#3619)
* test(lightwalletd): add a lightwalletd integration test * fix(lightwalletd): ignore the lightwalletd integration test by default
This commit is contained in:
parent
970f88ffcb
commit
78a05bcaf0
|
@ -27,7 +27,10 @@ use color_eyre::{
|
||||||
};
|
};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
use std::{collections::HashSet, convert::TryInto, env, path::Path, path::PathBuf, time::Duration};
|
use std::{
|
||||||
|
collections::HashSet, convert::TryInto, env, net::SocketAddr, path::Path, path::PathBuf,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use zebra_chain::{
|
use zebra_chain::{
|
||||||
block::Height,
|
block::Height,
|
||||||
|
@ -1452,6 +1455,154 @@ async fn tracing_endpoint() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: RPC endpoint and port conflict tests (#3165)
|
||||||
|
|
||||||
|
/// Launch `zebrad` with an RPC port, and make sure `lightwalletd` works with Zebra.
|
||||||
|
///
|
||||||
|
/// This test doesn't work on Windows, and it is ignored by default on other platforms.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
fn lightwalletd_integration() -> Result<()> {
|
||||||
|
zebra_test::init();
|
||||||
|
|
||||||
|
// Launch zebrad
|
||||||
|
|
||||||
|
// [Note on port conflict](#Note on port conflict)
|
||||||
|
let listen_port = random_known_port();
|
||||||
|
let listen_ip = "127.0.0.1".parse().expect("hard-coded IP is valid");
|
||||||
|
let listen_addr = SocketAddr::new(listen_ip, listen_port);
|
||||||
|
|
||||||
|
// Write a configuration that has the rpc listen_addr option set
|
||||||
|
// TODO: split this config into another function?
|
||||||
|
let mut config = default_test_config()?;
|
||||||
|
config.rpc.listen_addr = Some(listen_addr);
|
||||||
|
|
||||||
|
let dir = testdir()?.with_config(&mut config)?;
|
||||||
|
let mut zebrad = dir.spawn_child(&["start"])?.with_timeout(LAUNCH_DELAY);
|
||||||
|
|
||||||
|
// Wait until `zebrad` has opened the RPC endpoint
|
||||||
|
zebrad
|
||||||
|
.expect_stdout_line_matches(format!("Opened RPC endpoint at {}", listen_addr).as_str())?;
|
||||||
|
|
||||||
|
// Launch lightwalletd
|
||||||
|
// TODO: split this into another function
|
||||||
|
|
||||||
|
// Write a fake zcashd configuration that has the rpcbind and rpcport options set
|
||||||
|
// TODO: split this into another function
|
||||||
|
let dir = testdir()?;
|
||||||
|
let lightwalletd_config = format!(
|
||||||
|
"\
|
||||||
|
rpcbind={}\n\
|
||||||
|
rpcport={}\n\
|
||||||
|
",
|
||||||
|
listen_ip, listen_port
|
||||||
|
);
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
let path = dir.path().to_owned();
|
||||||
|
|
||||||
|
// TODO: split this into another function
|
||||||
|
if !config.state.ephemeral {
|
||||||
|
let cache_dir = path.join("state");
|
||||||
|
fs::create_dir_all(&cache_dir)?;
|
||||||
|
} else {
|
||||||
|
fs::create_dir_all(&path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let config_file = path.join("lightwalletd-zcash.conf");
|
||||||
|
fs::File::create(config_file)?.write_all(lightwalletd_config.as_bytes())?;
|
||||||
|
|
||||||
|
let result = {
|
||||||
|
let default_config_path = path.join("lightwalletd-zcash.conf");
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
default_config_path.exists(),
|
||||||
|
"lightwalletd requires a config"
|
||||||
|
);
|
||||||
|
|
||||||
|
dir.spawn_child_with_command(
|
||||||
|
"lightwalletd",
|
||||||
|
&[
|
||||||
|
// the fake zcashd conf we just wrote
|
||||||
|
"--zcash-conf-path",
|
||||||
|
default_config_path
|
||||||
|
.as_path()
|
||||||
|
.to_str()
|
||||||
|
.expect("Path is valid Unicode"),
|
||||||
|
// the lightwalletd cache directory
|
||||||
|
//
|
||||||
|
// TODO: create a sub-directory for lightwalletd
|
||||||
|
"--data-dir",
|
||||||
|
path.to_str().expect("Path is valid Unicode"),
|
||||||
|
// log to standard output
|
||||||
|
"--log-file",
|
||||||
|
"/dev/stdout",
|
||||||
|
// randomise wallet client ports
|
||||||
|
"--grpc-bind-addr",
|
||||||
|
"127.0.0.1:0",
|
||||||
|
"--http-bind-addr",
|
||||||
|
"127.0.0.1:0",
|
||||||
|
// don't require a TLS certificate
|
||||||
|
"--no-tls-very-insecure",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (lightwalletd, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
let mut lightwalletd = lightwalletd.with_timeout(LAUNCH_DELAY);
|
||||||
|
|
||||||
|
// Wait until `lightwalletd` has launched
|
||||||
|
let result = lightwalletd.expect_stdout_line_matches("Starting gRPC server");
|
||||||
|
let (_, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
|
||||||
|
// Check that `lightwalletd` is calling the expected Zebra RPCs
|
||||||
|
//
|
||||||
|
// TODO: add extra checks when we add new Zebra RPCs
|
||||||
|
|
||||||
|
// get_blockchain_info
|
||||||
|
let result = lightwalletd.expect_stdout_line_matches("Got sapling height");
|
||||||
|
let (_, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
|
||||||
|
let result = lightwalletd.expect_stdout_line_matches("Found 0 blocks in cache");
|
||||||
|
let (_, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
|
||||||
|
// Check that `lightwalletd` got to the first unimplemented Zebra RPC
|
||||||
|
//
|
||||||
|
// TODO: update the missing method name when we add a new Zebra RPC
|
||||||
|
|
||||||
|
let result = lightwalletd
|
||||||
|
.expect_stdout_line_matches("Method not found.*error zcashd getbestblockhash rpc");
|
||||||
|
let (_, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
let result = lightwalletd.expect_stdout_line_matches(
|
||||||
|
"Lightwalletd died with a Fatal error. Check logfile for details",
|
||||||
|
);
|
||||||
|
let (_, zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
|
||||||
|
// Cleanup both processes
|
||||||
|
|
||||||
|
let result = lightwalletd.kill();
|
||||||
|
let (_, mut zebrad) = zebrad.kill_on_error(result)?;
|
||||||
|
zebrad.kill()?;
|
||||||
|
|
||||||
|
let lightwalletd_output = lightwalletd.wait_with_output()?.assert_failure()?;
|
||||||
|
let zebrad_output = zebrad.wait_with_output()?.assert_failure()?;
|
||||||
|
|
||||||
|
// If the test fails here, see the [note on port conflict](#Note on port conflict)
|
||||||
|
//
|
||||||
|
// TODO: change lightwalletd to `assert_was_killed` when enough RPCs are implemented
|
||||||
|
lightwalletd_output
|
||||||
|
.assert_was_not_killed()
|
||||||
|
.wrap_err("Possible port conflict. Are there other acceptance tests running?")?;
|
||||||
|
zebrad_output
|
||||||
|
.assert_was_killed()
|
||||||
|
.wrap_err("Possible port conflict. Are there other acceptance tests running?")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Test will start 2 zebrad nodes one after the other using the same Zcash listener.
|
/// Test will start 2 zebrad nodes one after the other using the same Zcash listener.
|
||||||
/// It is expected that the first node spawned will get exclusive use of the port.
|
/// It is expected that the first node spawned will get exclusive use of the port.
|
||||||
/// The second node will panic with the Zcash listener conflict hint added in #1535.
|
/// The second node will panic with the Zcash listener conflict hint added in #1535.
|
||||||
|
|
Loading…
Reference in New Issue