Skip to content

Commit

Permalink
Only publish necessary ports for emulator container
Browse files Browse the repository at this point in the history
also make sure to randomize host port so that tests don't clobber each
other when ran in parallel
  • Loading branch information
elizabethengelman committed Jul 30, 2024
1 parent e1e69ae commit cba0bdc
Showing 1 changed file with 45 additions and 27 deletions.
72 changes: 45 additions & 27 deletions cmd/crates/stellar-ledger/tests/test/emulator_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use soroban_env_host::xdr::{self, Operation, OperationBody, Uint256};
use soroban_env_host::xdr::{Hash, Transaction};
use std::vec;

use std::net::TcpListener;
use stellar_ledger::hd_path::HdPath;
use stellar_ledger::{Blob, Error, LedgerSigner};

Expand All @@ -14,7 +15,7 @@ use stellar_xdr::curr::{
Memo, MuxedAccount, PaymentOp, Preconditions, SequenceNumber, TransactionExt,
};

use testcontainers::clients;
use testcontainers::{clients, core::Port, RunnableImage};
use tokio::time::sleep;

pub const TEST_NETWORK_PASSPHRASE: &[u8] = b"Test SDF Network ; September 2015";
Expand Down Expand Up @@ -44,11 +45,9 @@ use test_helpers::test::{
#[test_case("nanosp".to_string() ; "when the device is NanoS Plus")]
#[tokio::test]
async fn test_get_public_key(ledger_device_model: String) {
let args = Args {
ledger_device_model,
};
let runnable_image = get_runnable_image(ledger_device_model.clone());
let docker = clients::Cli::default();
let node = docker.run((Speculos::new(), args));
let node = docker.run(runnable_image);
let host_port = node.get_host_port_ipv4(9998);
let ui_host_port: u16 = node.get_host_port_ipv4(5000);
wait_for_emulator_start_text(ui_host_port).await;
Expand Down Expand Up @@ -78,11 +77,9 @@ async fn test_get_public_key(ledger_device_model: String) {
#[test_case("nanosp".to_string() ; "when the device is NanoS Plus")]
#[tokio::test]
async fn test_get_app_configuration(ledger_device_model: String) {
let args = Args {
ledger_device_model,
};
let runnable_image = get_runnable_image(ledger_device_model.clone());
let docker = clients::Cli::default();
let node = docker.run((Speculos::new(), args));
let node = docker.run(runnable_image);
let host_port = node.get_host_port_ipv4(9998);
let ui_host_port: u16 = node.get_host_port_ipv4(5000);
wait_for_emulator_start_text(ui_host_port).await;
Expand All @@ -108,11 +105,9 @@ async fn test_get_app_configuration(ledger_device_model: String) {
#[test_case("nanosp".to_string() ; "when the device is NanoS Plus")]
#[tokio::test]
async fn test_sign_tx(ledger_device_model: String) {
let args = Args {
ledger_device_model,
};
let runnable_image = get_runnable_image(ledger_device_model.clone());
let docker = clients::Cli::default();
let node = docker.run((Speculos::new(), args.clone()));
let node = docker.run(runnable_image);
let host_port = node.get_host_port_ipv4(9998);
let ui_host_port: u16 = node.get_host_port_ipv4(5000);
wait_for_emulator_start_text(ui_host_port).await;
Expand Down Expand Up @@ -175,7 +170,7 @@ async fn test_sign_tx(ledger_device_model: String) {
let ledger = Arc::clone(&ledger);
async move { ledger.sign_transaction(path, tx, test_network_hash()).await }
});
let approve = tokio::task::spawn(approve_tx_signature(ui_host_port, args.ledger_device_model));
let approve = tokio::task::spawn(approve_tx_signature(ui_host_port, ledger_device_model));

let result = sign.await.unwrap();
let _ = approve.await.unwrap();
Expand All @@ -199,12 +194,9 @@ async fn test_sign_tx(ledger_device_model: String) {
#[test_case("nanosp".to_string() ; "when the device is NanoS Plus")]
#[tokio::test]
async fn test_sign_tx_hash_when_hash_signing_is_not_enabled(ledger_device_model: String) {
let args = Args {
ledger_device_model,
};

let runnable_image = get_runnable_image(ledger_device_model.clone());
let docker = clients::Cli::default();
let node = docker.run((Speculos::new(), args));
let node = docker.run(runnable_image);
let host_port = node.get_host_port_ipv4(9998);
let ui_host_port: u16 = node.get_host_port_ipv4(5000);
wait_for_emulator_start_text(ui_host_port).await;
Expand All @@ -231,11 +223,9 @@ async fn test_sign_tx_hash_when_hash_signing_is_not_enabled(ledger_device_model:
#[test_case("nanosp".to_string() ; "when the device is NanoS Plus")]
#[tokio::test]
async fn test_sign_tx_hash_when_hash_signing_is_enabled(ledger_device_model: String) {
let args = Args {
ledger_device_model,
};
let runnable_image = get_runnable_image(ledger_device_model.clone());
let docker = clients::Cli::default();
let node = docker.run((Speculos::new(), args.clone()));
let node = docker.run(runnable_image);
let host_port = node.get_host_port_ipv4(9998);
let ui_host_port: u16 = node.get_host_port_ipv4(5000);

Expand All @@ -262,10 +252,7 @@ async fn test_sign_tx_hash_when_hash_signing_is_enabled(ledger_device_model: Str
let ledger = Arc::clone(&ledger);
async move { ledger.sign_transaction_hash(path, &test_hash).await }
});
let approve = tokio::task::spawn(approve_tx_hash_signature(
ui_host_port,
args.ledger_device_model,
));
let approve = tokio::task::spawn(approve_tx_hash_signature(ui_host_port, ledger_device_model));

let response = sign.await.unwrap();
let _ = approve.await.unwrap();
Expand Down Expand Up @@ -338,6 +325,37 @@ struct EventsResponse {
events: Vec<EmulatorEvent>,
}

fn get_runnable_image(ledger_device_model: String) -> RunnableImage<Speculos> {
let args = Args {
ledger_device_model,
};
let runnable_image: RunnableImage<Speculos> = (Speculos::new(), args).into();

// doing this to randomize the ports on the host so that parallel tests don't clobber each other
let (tcp_port_1, tcp_port_2) = get_available_ports();
runnable_image
.with_mapped_port(Port {
local: tcp_port_1,
internal: 9998,
})
.with_mapped_port(Port {
local: tcp_port_2,
internal: 5000,
})
}

fn get_available_ports() -> (u16, u16) {
let listener1 = TcpListener::bind("127.0.0.1:0").unwrap();
let listener2 = TcpListener::bind("127.0.0.1:0").unwrap();
println!("listener1: {:?}", listener1);
let port_1 = listener1.local_addr().unwrap().port();
let port_2 = listener2.local_addr().unwrap().port();
drop(listener1);
drop(listener2);

(port_1, port_2)
}

fn get_http_transport(host: &str, port: u16) -> Result<impl Exchange, Error> {
Ok(EmulatorHttpTransport::new(host, port))
}
Expand Down

0 comments on commit cba0bdc

Please sign in to comment.