Skip to content

Commit

Permalink
Rewrite integration test harness #69
Browse files Browse the repository at this point in the history
  • Loading branch information
marsella committed Jan 27, 2022
1 parent 5380f01 commit 93c1e81
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 81 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,8 @@ strum_macros = "0.21"

[build-dependencies]
canonicalize_json_micheline = { path = "src/canonicalize_json_micheline" }

[[test]]
name = "integration_tests"
path = "integration_tests/main.rs"
harness = false
108 changes: 52 additions & 56 deletions tests/common/mod.rs → integration_tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{
collections::HashMap,
fs::File,
io::{Read, Write},
sync::{Mutex, Once},
sync::Mutex,
};

use futures::future::Join;
Expand All @@ -13,45 +13,16 @@ use {
thiserror::Error,
tracing::{error, info, info_span},
tracing_futures::Instrument,
zeekoe::timeout::WithTimeout,
};

lazy_static::lazy_static!(
static ref FUTURE: Join<JoinHandle<()>, JoinHandle<()>> = {
// Stand-in task for the customer watcher.
let one = tokio::spawn(
async {
loop {
error!("This task worked exactly like I expected it to");
tokio::time::sleep(tokio::time::Duration::new(3,0)).await;
}
}
.instrument(info_span!("customer watcher")),
);

// Stand-in task for the merchant server
let two = tokio::spawn(
async {
loop {
error!("This task is also good at its job");
tokio::time::sleep(tokio::time::Duration::new(5, 0)).await;
}
}
.instrument(info_span!("merchant server")),
);

// TODO: This is never awaited so it never runs. Unfortunately, anywhere
// that we await it will have to... wait
future::join(one, two)
};
);

static BEGIN_SETUP: Once = Once::new();

pub const CUSTOMER_CONFIG: &str = "TestCustomer.toml";
pub const MERCHANT_CONFIG: &str = "TestMerchant.toml";

pub const ERROR_FILENAME: &str = "errors.log";

// Give a name to the slightly annoying type of the joined server futures
type ServerFuture = Join<JoinHandle<()>, JoinHandle<()>>;

#[derive(Debug)]
#[allow(unused)]
pub enum Party {
Expand All @@ -69,27 +40,48 @@ impl Party {
}
}

pub async fn setup() {
// This is goofy because `Once` does not support asynchronous functions, but our setup
// requires spawning a bunch of processes.
if !BEGIN_SETUP.is_completed() {
BEGIN_SETUP.call_once(|| {
// write config options for each party
write_config_file(CUSTOMER_CONFIG, customer_test_config());
write_config_file(MERCHANT_CONFIG, merchant_test_config());

// TODO: this is not logging spans as expected.
tracing_subscriber::fmt()
.with_writer(Mutex::new(
File::create(ERROR_FILENAME).expect("Failed to open log file"),
))
.init();
info!("spawning tasks now...");

// Force initialization of the lazy_static variable
let _intentional_access = &FUTURE;
});
}
pub async fn setup() -> ServerFuture {
// write config options for each party
write_config_file(CUSTOMER_CONFIG, customer_test_config());
write_config_file(MERCHANT_CONFIG, merchant_test_config());

tracing_subscriber::fmt()
.with_writer(Mutex::new(
File::create(ERROR_FILENAME).expect("Failed to open log file"),
))
.init();
info!("spawning tasks now...");

// Stand-in task for the customer watcher.
let one = tokio::spawn(
async {
loop {
error!("This task worked exactly like I expected it to");
tokio::time::sleep(tokio::time::Duration::new(3, 0)).await;
}
}
.instrument(info_span!("customer watcher")),
);

// Stand-in task for the merchant server
let two = tokio::spawn(
async {
loop {
error!("This task is also good at its job");
tokio::time::sleep(tokio::time::Duration::new(5, 0)).await;
}
}
.instrument(info_span!("merchant server")),
);

future::join(one, two)
}

pub async fn teardown(server_future: ServerFuture) {
// Ignore the result because we expect it to be an `Expired` error
let _result = server_future
.with_timeout(tokio::time::Duration::new(1, 0))
.await;
}

/// Encode the customizable fields of the zeekoe customer Config struct for testing.
Expand Down Expand Up @@ -156,12 +148,16 @@ pub enum LogError {
ReadFailed(std::io::Error),
}

/// Get any errors from the log file.
///
/// Current behavior: outputs the entire log
/// Ideal behavior: pass a Party, maybe an indicator of which test / channel name we want. Return
/// only the lines relevant to that setting.
pub fn get_error() -> Result<String, LogError> {
let mut file = File::open(ERROR_FILENAME).map_err(LogError::OpenFailed)?;
let mut error = String::new();
file.read_to_string(&mut error)
.map_err(LogError::ReadFailed)?;

// todo: maybe parse this into the last line or something
Ok(error)
}
58 changes: 58 additions & 0 deletions integration_tests/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
pub(crate) mod common;

use std::panic;

#[tokio::main]
pub async fn main() {
let server_future = common::setup().await;

// Run tests
let tests = &[failing_test, another_failing_test];
setup_works().await;

// Run every test, printing out details if it fails
let results = tests
.into_iter()
.map(|test| {
let result = panic::catch_unwind(|| test());
if result.is_err() {
eprintln!("Test failed <details>\n")
}
result
})
.collect::<Vec<_>>();

// Fail if any test failed. This is separate from evaluation to enforce that _every_ test must
// run -- otherwise, any will short-circuit the execution
assert!(results.iter().any(|result| result.is_err()));

common::teardown(server_future).await;
}

async fn setup_works() {
// Make sure that the config files were encoded validly
let _customer_config = zeekoe::customer::Config::load(common::CUSTOMER_CONFIG)
.await
.expect("failed to load customer config");

let _merch_config = zeekoe::merchant::Config::load(common::MERCHANT_CONFIG)
.await
.expect("failed to load merchant config");

// Make sure that errors are written to the error log
match common::get_error() {
Ok(string) => {
println!("{}", string);
assert!(string.contains("This task is also good"))
}
Err(_) => assert!(false),
}
}

fn failing_test() {
panic!("this test failed :)")
}

fn another_failing_test() {
assert_eq!(100, 3)
}
25 changes: 0 additions & 25 deletions tests/tezos.rs

This file was deleted.

0 comments on commit 93c1e81

Please sign in to comment.