Skip to content

Commit

Permalink
#414: refactor: add commonly used test utils
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-kuprianov committed Aug 6, 2020
1 parent d65a72e commit a720487
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 115 deletions.
41 changes: 12 additions & 29 deletions tendermint/tests/lite-model-based.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::{process, io};
use std::io::Read;
use std::{io};
use std::{fs, path::PathBuf};
use serde::Deserialize;
use tempfile::tempdir;
use tendermint::{block::signed_header::SignedHeader, evidence::Duration, lite, Hash, Time};
use tendermint::block::{Header, Height};
use tendermint::lite::{Requester, TrustThresholdFraction, TrustedState};
mod lite_tests;
use lite_tests::*;
use tendermint::lite::error::Error;
//use tempfile::tempdir;
use tendermint::{block::signed_header::SignedHeader, lite};
use tendermint::block::{Header};
use tendermint::lite::{TrustThresholdFraction, TrustedState};

mod utils;
use utils::{apalache::*, command::*, lite::*};

type Trusted = lite::TrustedState<SignedHeader, Header>;

Expand Down Expand Up @@ -49,24 +48,6 @@ pub struct BlockVerdict {
verdict: LiteVerdict,
}

#[derive(Deserialize, Clone, Debug)]
pub struct ApalacheTestBatch {
pub description: String,
pub kind: LiteTestKind,
pub model: String,
pub length: Option<u64>,
pub timeout: Option<u64>,
pub tests: Vec<String>,
}

#[derive(Deserialize, Clone, Debug)]
pub struct ApalacheTestCase {
pub model: String,
pub test: String,
pub length: Option<u64>,
pub timeout: Option<u64>,
}

const TEST_DIR: &str = "./tests/support/lite-model-based/";

fn read_file(dir: &str, file: &str) -> String {
Expand Down Expand Up @@ -126,8 +107,6 @@ fn single_step_test() {
run_single_step_test(&tc);
}



fn run_apalache_test(dir: &str, test: ApalacheTestCase) -> io::Result<CommandRun> {
let mut cmd = Command::new();
if let Some(timeout) = test.timeout {
Expand Down Expand Up @@ -163,6 +142,10 @@ fn run_apalache_test(dir: &str, test: ApalacheTestCase) -> io::Result<CommandRun

#[test]
fn apalache_test() {

println!("Apalache: {}", Command::exists_program("apalache-mc"));
println!("Jsonatr: {}", Command::exists_program("jsonatr"));

let test = ApalacheTestCase {
model: "MC4_4_faulty.tla".to_string(),
test: "TestFailureInv".to_string(),
Expand Down
4 changes: 2 additions & 2 deletions tendermint/tests/lite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use tendermint::block::{Header, Height};
use tendermint::lite::{Requester, TrustThresholdFraction, TrustedState};
use tendermint::{block::signed_header::SignedHeader, evidence::Duration, lite, Hash, Time};

mod lite_tests;
use lite_tests::*;
mod utils;
use utils::lite::*;

#[derive(Deserialize, Clone, Debug)]
struct TestCases {
Expand Down
18 changes: 18 additions & 0 deletions tendermint/tests/utils/apalache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::Deserialize;

#[derive(Deserialize, Clone, Debug)]
pub struct ApalacheTestBatch {
pub description: String,
pub model: String,
pub length: Option<u64>,
pub timeout: Option<u64>,
pub tests: Vec<String>,
}

#[derive(Deserialize, Clone, Debug)]
pub struct ApalacheTestCase {
pub model: String,
pub test: String,
pub length: Option<u64>,
pub timeout: Option<u64>,
}
88 changes: 88 additions & 0 deletions tendermint/tests/utils/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::{process, io};
use std::io::Read;

/// A thin wrapper around process::Command to facilitate running external commands.
pub struct Command {
program: Option<String>,
args: Vec<String>,
dir: Option<String>
}

impl Command {

/// Check whether the given program can be executed
pub fn exists_program(program: &str) -> bool {
Command::new().program(program).spawn().is_ok()
}

/// Constructs a new Command for the given program with arguments.
pub fn new() -> Command {
Command {
program: None,
args: vec![],
dir: None
}
}

/// Sets the program to run
pub fn program(&mut self, program: &str) -> &mut Self {
self.program = Some(program.to_owned());
self
}

/// Adds a new program argument
pub fn arg(&mut self, arg: &str) -> &mut Self {
self.args.push(arg.to_owned());
self
}

/// Adds a new program argument, concatenated from several parts
pub fn arg_from_parts(&mut self, parts: Vec<&str>) -> &mut Self {
let mut arg: String = String::new();
for part in parts {
arg = arg + part;
}
self.args.push(arg);
self
}

/// Sets the working directory for the child process
pub fn current_dir(&mut self, dir: &str) -> &mut Self {
self.dir = Some(dir.to_owned());
self
}

/// Executes the command as a child process, and extracts its status, stdout, stderr.
pub fn spawn(&mut self) -> io::Result<CommandRun> {
match &self.program {
None => Err(io::Error::new(io::ErrorKind::InvalidInput, "")),
Some(program) => {
let mut command = process::Command::new(program);
command.args(&self.args)
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped());
if let Some(dir) = &self.dir {
command.current_dir(dir);
}
let mut process = command.spawn()?;
let status = process.wait()?;
let mut stdout = String::new();
process.stdout.unwrap().read_to_string(&mut stdout)?;
let mut stderr = String::new();
process.stderr.unwrap().read_to_string(&mut stderr)?;
Ok(CommandRun {
status,
stdout,
stderr
})
}
}
}
}

/// The result of a command execution if managed to run the child process
pub struct CommandRun {
pub status: process::ExitStatus,
pub stdout: String,
pub stderr: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ use tendermint::lite::Requester;
use tendermint::{
block::signed_header::SignedHeader, evidence::Duration, lite, validator::Set, Time,
};
use std::{process, io};
use std::io::Read;

/// Test that a struct `T` can be:
///
/// - serialized to JSON
/// - parsed back from the serialized JSON of the previous step
/// - that the two parsed structs are equal according to their `PartialEq` impl
pub fn test_serialization_roundtrip<T>(obj: &T)
where
T: Debug + PartialEq + Serialize + DeserializeOwned,
where
T: Debug + PartialEq + Serialize + DeserializeOwned,
{
let serialized = serde_json::to_string(obj).unwrap();
let parsed = serde_json::from_str(&serialized).unwrap();
Expand Down Expand Up @@ -92,83 +90,3 @@ impl MockRequester {
}
}
}

/// A thin wrapper around process::Command to facilitate running external commands.
pub struct Command {
program: Option<String>,
args: Vec<String>,
dir: Option<String>
}

impl Command {
/// Constructs a new Command for the given program with arguments.
pub fn new() -> Command {
Command {
program: None,
args: vec![],
dir: None
}
}

/// Sets the program to run
pub fn program(&mut self, program: &str) -> &mut Self {
self.program = Some(program.to_owned());
self
}

/// Adds a new program argument
pub fn arg(&mut self, arg: &str) -> &mut Self {
self.args.push(arg.to_owned());
self
}

/// Adds a new program argument, concatenated from several parts
pub fn arg_from_parts(&mut self, parts: Vec<&str>) -> &mut Self {
let mut arg: String = String::new();
for part in parts {
arg = arg + part;
}
self.args.push(arg);
self
}

/// Sets the working directory for the child process
pub fn current_dir(&mut self, dir: &str) -> &mut Self {
self.dir = Some(dir.to_owned());
self
}

/// Executes the command as a child process, and extracts its status, stdout, stderr.
pub fn spawn(&mut self) -> io::Result<CommandRun> {
match &self.program {
None => Err(io::Error::new(io::ErrorKind::InvalidInput, "")),
Some(program) => {
let mut command = process::Command::new(program);
command.args(&self.args)
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped());
if let Some(dir) = &self.dir {
command.current_dir(dir);
}
let mut process = command.spawn()?;
let status = process.wait()?;
let mut stdout = String::new();
process.stdout.unwrap().read_to_string(&mut stdout)?;
let mut stderr = String::new();
process.stderr.unwrap().read_to_string(&mut stderr)?;
Ok(CommandRun {
status,
stdout,
stderr
})
}
}
}
}

/// The result of a command execution if managed to run the child process
pub struct CommandRun {
pub status: process::ExitStatus,
pub stdout: String,
pub stderr: String
}
3 changes: 3 additions & 0 deletions tendermint/tests/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod apalache;
pub mod command;
pub mod lite;

0 comments on commit a720487

Please sign in to comment.