Skip to content
Permalink
Browse files

basic explorer transaction scenario test

  • Loading branch information...
enzoc4 committed Oct 9, 2019
1 parent 5ddbe91 commit 9161927edbc616ce60a07c3afc20d224a5d86d83
@@ -7,6 +7,7 @@ pub mod node;
mod programs;
#[macro_use]
pub mod scenario;
mod graphql;
mod slog;
pub mod style;
mod wallet;
@@ -55,7 +55,45 @@ fn main() {

introduction(&context);

scenario_2(context.derive());
// FIXME: Can be abstracted as a macro? Maybe a procedural one (attributes?)
let tests = vec![
Test {
func: Box::new(move |context| explorer_get_transaction(context)),
name: "test explorer transaction".to_owned(),
ignore: false,
},
Test {
func: Box::new(move |context| scenario_1(context)),
name: "scenario 1".to_owned(),
ignore: false,
},
Test {
func: Box::new(move |context| scenario_2(context)),
name: "scenario 2".to_owned(),
ignore: true,
},
];

for test in tests.iter().filter(|t| !t.ignore) {
let context = context.derive();
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || (test.func)(context))) {
Ok(()) => println!("{} PASSED", test.name),
Err(e) => {
println!("{} FAILED", test.name);

let msg = e
.downcast_ref::<String>()
.map(|e| &**e)
.or_else(|| e.downcast_ref::<&'static str>().map(|e| *e))
.unwrap_or("Unknown");

println!("Cause: {}", msg);

// Return a non 0 exit status
std::process::exit(1);
}
}
}
}

fn introduction<R: rand_core::RngCore>(context: &Context<R>) {
@@ -197,3 +235,66 @@ pub fn scenario_2(mut context: Context<ChaChaRng>) {

controller.finalize();
}

pub fn explorer_get_transaction(mut context: Context<ChaChaRng>) {
let scenario_settings = prepare_scenario! {
"Testing the explorer",
&mut context,
topology [
"Leader1",
]
blockchain {
consensus = GenesisPraos,
number_of_slots_per_epoch = 60,
slot_duration = 1,
leaders = [ "Leader1" ],
initials = [
account "unassigned1" with 500_000_000,
account "unassigned2" with 100_000_000,
account "delegated1" with 2_000_000_000 delegates to "Leader1",
],
}
};

let mut controller = scenario_settings.build(context).unwrap();

let leader1 = controller.spawn_node("Leader1", true).unwrap();
thread::sleep(Duration::from_secs(1));

controller.monitor_nodes();

let mut wallet1 = controller.wallet("unassigned1").unwrap();
let wallet2 = controller.wallet("delegated1").unwrap();

let check = controller
.wallet_send_to(&mut wallet1, &wallet2, &leader1, 5_000.into())
.unwrap();

let id = check.fragment_id;

thread::sleep(Duration::from_secs(1));

let leader_status = leader1.wait_fragment(Duration::from_secs(2), check);

if let Ok(status) = leader_status {
if status.is_in_a_block() {
wallet1.confirm_transaction();
assert!(
leader1.get_explorer_transaction(id).is_ok(),
"transaction not found in explorer"
);
}
}

thread::sleep(Duration::from_secs(1));

leader1.shutdown().unwrap();

controller.finalize();
}

pub struct Test {
pub func: Box<dyn Fn(Context<ChaChaRng>)>,
pub name: String,
pub ignore: bool,
}
@@ -1,12 +1,15 @@
use crate::graphql::{ExplorerTransaction, GraphQLQuery, GraphQLResponse};
use crate::{scenario::settings::NodeSetting, style, Context, NodeAlias};
use bawawa::{Control, Process};
use chain_impl_mockchain::{
block::{Block, HeaderHash},
fragment::{Fragment, FragmentId},
};
use indicatif::ProgressBar;
use jormungandr_lib::crypto::hash::Hash;
use jormungandr_lib::interfaces::{FragmentLog, FragmentStatus};
use rand_core::RngCore;
use std::convert::TryFrom;
use std::{
collections::HashMap,
path::PathBuf,
@@ -21,6 +24,7 @@ error_chain! {
Io(std::io::Error);
Reqwest(reqwest::Error);
BlockFormatError(chain_core::mempack::ReadError);
JsonError(serde_json::error::Error);
}

errors {
@@ -55,7 +59,8 @@ error_chain! {
}

pub struct MemPoolCheck {
fragment_id: FragmentId,
// FIXME: Probably this shouldn't be pub, maybe as_ref?
pub fragment_id: FragmentId,
}

pub enum NodeBlock0 {
@@ -117,7 +122,7 @@ impl NodeController {
self.status() == Status::Running
}

fn post(&self, path: &str, body: Vec<u8>) -> Result<reqwest::Response> {
fn post(&self, path: &str, body: impl Into<reqwest::Body>) -> Result<reqwest::Response> {
self.progress_bar.log_info(format!("POST '{}'", path));

let client = reqwest::Client::new();
@@ -136,6 +141,23 @@ impl NodeController {
}
}

fn query_explorer(&self, query: GraphQLQuery) -> Result<reqwest::Response> {
let client = reqwest::Client::new();
let res = client
.post(&format!("{}", self.base_explorer_url()))
.json(&query)
.send();

match res {
Err(err) => {
self.progress_bar
.log_err(format!("Failed to send request {}", &err));
Err(err.into())
}
Ok(r) => Ok(r),
}
}

fn get(&self, path: &str) -> Result<reqwest::Response> {
self.progress_bar.log_info(format!("GET '{}'", path));

@@ -153,6 +175,13 @@ impl NodeController {
format!("http://{}/api/v0", self.settings.config.rest.listen.clone())
}

fn base_explorer_url(&self) -> String {
format!(
"http://{}/explorer/graphql",
self.settings.config.rest.listen.clone()
)
}

pub fn send_fragment(&self, fragment: Fragment) -> Result<MemPoolCheck> {
use chain_core::property::Fragment as _;
use chain_core::property::Serialize as _;
@@ -264,6 +293,16 @@ impl NodeController {
}
}

pub fn get_explorer_transaction(&self, fragment_id: FragmentId) -> Result<ExplorerTransaction> {
let query = ExplorerTransaction::build_query(fragment_id);

let response = self.query_explorer(query);

let response: GraphQLResponse = serde_json::from_str(&response?.text()?)?;

ExplorerTransaction::try_from(response).map_err(|e| e.into())
}

pub fn shutdown(&self) -> Result<bool> {
let result = self.get("shutdown")?.text()?;

@@ -47,6 +47,8 @@ pub struct NodeConfig {
pub rest: Rest,

pub p2p: P2pConfig,

pub explorer: Explorer,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -64,6 +66,11 @@ pub struct P2pConfig {
pub trusted_peers: Vec<poldercast::Address>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Explorer {
pub enabled: bool,
}

/// Node Secret(s)
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct NodeSecret {
@@ -404,6 +411,7 @@ impl NodeConfig {
NodeConfig {
rest: Rest::prepare(context),
p2p: P2pConfig::prepare(context),
explorer: Explorer { enabled: true },
}
}
}

0 comments on commit 9161927

Please sign in to comment.
You can’t perform that action at this time.