Use only the RunnerOptions struct when running a Hurl File/Entry

This commit is contained in:
Fabrice Reix 2022-09-02 15:59:28 +02:00
parent 91f7396a6d
commit fefab14152
No known key found for this signature in database
GPG Key ID: BF5213154B2E7155
6 changed files with 141 additions and 108 deletions

View File

@ -27,11 +27,11 @@ use colored::*;
use hurl::cli;
use hurl::cli::{CliError, CliOptions, Logger, OutputType};
use hurl::http;
use hurl::http::{ContextDir, Verbosity};
use hurl::http::ContextDir;
use hurl::report;
use hurl::report::canonicalize_filename;
use hurl::runner;
use hurl::runner::{HurlResult, RunnerError, RunnerOptions};
use hurl::runner::{HurlResult, RunnerError, RunnerOptions, Verbosity};
use hurl::util::logger::BaseLogger;
use hurl_core::ast::{Entry, Pos, SourceInfo};
use hurl_core::error::Error;
@ -163,24 +163,6 @@ fn execute(
};
let context_dir = ContextDir::new(current_dir, file_root);
let client_options = http::ClientOptions {
cacert_file,
follow_location,
max_redirect,
cookie_input_file,
proxy,
no_proxy,
verbosity,
insecure,
timeout,
connect_timeout,
user,
user_agent,
compressed,
};
let mut client = http::Client::new(&client_options);
let pre_entry = if cli_options.interactive {
Some(cli::interactive::pre_entry as fn(Entry) -> bool)
} else {
@ -197,23 +179,49 @@ fn execute(
let ignore_asserts = cli_options.ignore_asserts;
let very_verbose = cli_options.very_verbose;
let runner_options = RunnerOptions {
cacert_file,
compressed,
fail_fast,
variables,
to_entry,
user,
context_dir,
ignore_asserts,
insecure,
max_redirect,
very_verbose,
pre_entry,
proxy,
post_entry,
connect_timeout,
cookie_input_file,
follow_location,
no_proxy,
timeout,
user_agent,
verbosity,
};
let result = runner::run(
&hurl_file,
filename,
&mut client,
&runner_options,
&client_options,
logger,
);
let client_options = http::ClientOptions {
cacert_file: runner_options.cacert_file.clone(),
follow_location: runner_options.follow_location,
max_redirect: runner_options.max_redirect,
cookie_input_file: runner_options.cookie_input_file.clone(),
proxy: runner_options.proxy.clone(),
no_proxy: runner_options.no_proxy.clone(),
verbosity: runner_options.verbosity.as_ref().map(|v| match v {
Verbosity::Verbose => http::Verbosity::Verbose,
Verbosity::VeryVerbose => http::Verbosity::VeryVerbose,
}),
insecure: runner_options.insecure,
timeout: runner_options.timeout,
connect_timeout: runner_options.connect_timeout,
user: runner_options.user.clone(),
user_agent: runner_options.user_agent.clone(),
compressed: runner_options.compressed,
};
let mut client = http::Client::new(&client_options);
let result = runner::run(&hurl_file, filename, &mut client, &runner_options, logger);
if cli_options.progress {
logger.test_completed(&result);
}

View File

@ -17,6 +17,7 @@
*/
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
use crate::http;
use crate::http::ContextDir;
@ -26,14 +27,61 @@ use super::value::Value;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RunnerOptions {
pub fail_fast: bool,
pub variables: HashMap<String, Value>,
pub to_entry: Option<usize>,
pub cacert_file: Option<String>,
pub compressed: bool,
pub connect_timeout: Duration,
pub context_dir: ContextDir,
pub cookie_input_file: Option<String>,
pub fail_fast: bool,
pub follow_location: bool,
pub ignore_asserts: bool,
pub very_verbose: bool, // If true, log body response in verbose mode.
pub pre_entry: Option<fn(Entry) -> bool>,
pub insecure: bool,
pub max_redirect: Option<usize>,
pub no_proxy: Option<String>,
pub post_entry: Option<fn() -> bool>,
pub pre_entry: Option<fn(Entry) -> bool>,
pub proxy: Option<String>,
pub timeout: Duration,
pub to_entry: Option<usize>,
pub user: Option<String>,
pub user_agent: Option<String>,
pub variables: HashMap<String, Value>,
pub verbosity: Option<Verbosity>,
pub very_verbose: bool, // If true, log body response in verbose mode.
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Verbosity {
Verbose,
VeryVerbose,
}
impl Default for RunnerOptions {
fn default() -> Self {
RunnerOptions {
cacert_file: None,
compressed: false,
connect_timeout: Duration::from_secs(300),
context_dir: Default::default(),
cookie_input_file: None,
fail_fast: false,
follow_location: false,
ignore_asserts: false,
insecure: false,
max_redirect: Some(50),
no_proxy: None,
post_entry: None,
pre_entry: None,
proxy: None,
timeout: Duration::from_secs(300),
to_entry: None,
user: None,
user_agent: None,
variables: Default::default(),
verbosity: None,
very_verbose: false,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -19,7 +19,6 @@ use std::collections::HashMap;
use crate::cli::Logger;
use crate::http;
use crate::http::{ClientOptions, Verbosity};
use hurl_core::ast::*;
use super::core::*;
@ -39,7 +38,6 @@ pub fn run(
http_client: &mut http::Client,
variables: &mut HashMap<String, Value>,
runner_options: &RunnerOptions,
client_options: &ClientOptions,
logger: &Logger,
) -> Vec<EntryResult> {
let http_request = match eval_request(&entry.request, variables, &runner_options.context_dir) {
@ -52,23 +50,42 @@ pub fn run(
asserts: vec![],
errors: vec![error],
time_in_ms: 0,
compressed: client_options.compressed,
compressed: runner_options.compressed,
}];
}
};
let client_options = http::ClientOptions {
cacert_file: runner_options.cacert_file.clone(),
follow_location: runner_options.follow_location,
max_redirect: runner_options.max_redirect,
cookie_input_file: runner_options.cookie_input_file.clone(),
proxy: runner_options.proxy.clone(),
no_proxy: runner_options.no_proxy.clone(),
verbosity: runner_options.verbosity.as_ref().map(|v| match v {
Verbosity::Verbose => http::Verbosity::Verbose,
Verbosity::VeryVerbose => http::Verbosity::VeryVerbose,
}),
insecure: runner_options.insecure,
timeout: runner_options.timeout,
connect_timeout: runner_options.connect_timeout,
user: runner_options.user.clone(),
user_agent: runner_options.user_agent.clone(),
compressed: runner_options.compressed,
};
// Experimental features
// with cookie storage
use std::str::FromStr;
if let Some(s) = cookie_storage_set(&entry.request) {
if let Ok(cookie) = http::Cookie::from_str(s.as_str()) {
http_client.add_cookie(&cookie, client_options);
http_client.add_cookie(&cookie, &client_options);
} else {
logger.warning(format!("Cookie string can not be parsed: '{}'", s).as_str());
}
}
if cookie_storage_clear(&entry.request) {
http_client.clear_cookie_storage(client_options);
http_client.clear_cookie_storage(&client_options);
}
logger.debug("");
@ -81,12 +98,12 @@ pub fn run(
logger.debug("Request can be run with the following curl command:");
logger.debug(
http_client
.curl_command_line(&http_request, &runner_options.context_dir, client_options)
.curl_command_line(&http_request, &runner_options.context_dir, &client_options)
.as_str(),
);
logger.debug("");
let calls = match http_client.execute_with_redirect(&http_request, client_options, logger) {
let calls = match http_client.execute_with_redirect(&http_request, &client_options, logger) {
Ok(calls) => calls,
Err(http_error) => {
let runner_error = RunnerError::from(http_error);
@ -228,16 +245,16 @@ fn log_request_spec(request: &http::RequestSpec, logger: &Logger) {
logger.debug("");
}
/// Returns a new [`ClientOptions`] based on the `entry` optional Options section
/// and a default `client_options`.
/// Returns a new [`RunnerOptions`] based on the `entry` optional Options section
/// and a default `runner_options`.
pub fn get_entry_options(
entry: &Entry,
client_options: &ClientOptions,
runner_options: &RunnerOptions,
logger: &Logger,
) -> ClientOptions {
let mut client_options = client_options.clone();
) -> RunnerOptions {
let mut runner_options = runner_options.clone();
if !has_options(entry) {
return client_options;
return runner_options;
}
logger.debug("");
@ -248,27 +265,27 @@ pub fn get_entry_options(
for option in options {
match option {
EntryOption::CaCertificate(option) => {
client_options.cacert_file = Some(option.filename.value.clone());
runner_options.cacert_file = Some(option.filename.value.clone());
logger.debug(format!("cacert: {}", option.filename.value).as_str());
}
EntryOption::Compressed(option) => {
client_options.compressed = option.value;
runner_options.compressed = option.value;
logger.debug(format!("compressed: {}", option.value).as_str());
}
EntryOption::Insecure(option) => {
client_options.insecure = option.value;
runner_options.insecure = option.value;
logger.debug(format!("insecure: {}", option.value).as_str());
}
EntryOption::FollowLocation(option) => {
client_options.follow_location = option.value;
runner_options.follow_location = option.value;
logger.debug(format!("location: {}", option.value).as_str());
}
EntryOption::MaxRedirect(option) => {
client_options.max_redirect = Some(option.value);
runner_options.max_redirect = Some(option.value);
logger.debug(format!("max-redirs: {}", option.value).as_str());
}
EntryOption::Verbose(option) => {
client_options.verbosity = if option.value {
runner_options.verbosity = if option.value {
Some(Verbosity::Verbose)
} else {
None
@ -277,7 +294,7 @@ pub fn get_entry_options(
}
EntryOption::VeryVerbose(option) => {
client_options.verbosity = if option.value {
runner_options.verbosity = if option.value {
Some(Verbosity::VeryVerbose)
} else {
None
@ -288,7 +305,7 @@ pub fn get_entry_options(
}
}
}
client_options
runner_options
}
/// Returns [`true`] if this `entry` has an Option section, [`false`] otherwise.

View File

@ -20,7 +20,6 @@ use std::time::Instant;
use crate::cli::Logger;
use crate::http;
use crate::http::ClientOptions;
use crate::runner::entry::get_entry_verbosity;
use hurl_core::ast::*;
@ -57,17 +56,10 @@ use super::entry;
/// let logger = Logger::new(false, false, filename, s);
///
/// // Define runner options
/// let variables = std::collections::HashMap::new();
/// let runner_options = runner::RunnerOptions {
/// fail_fast: false,
/// variables,
/// to_entry: None,
/// context_dir: ContextDir::default(),
/// ignore_asserts: false,
/// very_verbose: false,
/// pre_entry: None,
/// post_entry: None,
/// };
/// very_verbose: true,
/// ..runner::RunnerOptions::default()
/// };
///
/// // Run the hurl file
/// let hurl_results = runner::run(
@ -75,8 +67,7 @@ use super::entry;
/// filename,
/// &mut client,
/// &runner_options,
/// &client_options,
/// &logger,
/// &logger
/// );
/// assert!(hurl_results.success);
/// ```
@ -85,7 +76,6 @@ pub fn run(
filename: &str,
http_client: &mut http::Client,
runner_options: &RunnerOptions,
client_options: &ClientOptions,
logger: &Logger,
) -> HurlResult {
let mut entries = vec![];
@ -119,7 +109,7 @@ pub fn run(
// We compute these new overridden options for this entry, before entering into the `run`
// function because entry options can modify the logger and we want the preamble
// "Executing entry..." to be displayed based on the entry level verbosity.
let entry_verbosity = get_entry_verbosity(entry, &client_options.verbosity);
let entry_verbosity = get_entry_verbosity(entry, &runner_options.verbosity);
let logger = &Logger::new(
logger.color,
entry_verbosity.is_some(),
@ -132,16 +122,9 @@ pub fn run(
);
logger.debug_important(format!("Executing entry {}", entry_index + 1).as_str());
let client_options = entry::get_entry_options(entry, client_options, logger);
let runner_options = entry::get_entry_options(entry, runner_options, logger);
let entry_results = entry::run(
entry,
http_client,
&mut variables,
runner_options,
&client_options,
logger,
);
let entry_results = entry::run(entry, http_client, &mut variables, &runner_options, logger);
for entry_result in &entry_results {
for e in &entry_result.errors {

View File

@ -25,6 +25,7 @@
pub use self::core::{
AssertResult, CaptureResult, EntryResult, Error, HurlResult, RunnerError, RunnerOptions,
Verbosity,
};
pub use self::hurl_file::run;
pub use self::value::Value;

View File

@ -16,15 +16,15 @@
*
*/
use std::collections::HashMap;
use hurl::cli;
use hurl::cli::Logger;
use hurl::http;
use hurl::http::ContextDir;
use hurl::runner;
use hurl::runner::RunnerOptions;
use hurl_core::ast::*;
use hurl_core::parser;
use std::collections::HashMap;
// Can be used for debugging
#[test]
@ -38,24 +38,12 @@ fn test_hurl_file() {
let logger = Logger::new(false, false, filename, &content);
let runner_options = RunnerOptions {
fail_fast: false,
variables,
to_entry: None,
context_dir: ContextDir::default(),
ignore_asserts: false,
very_verbose: false,
pre_entry: None,
post_entry: None,
..RunnerOptions::default()
};
let _hurl_log = runner::run(
&hurl_file,
filename,
&mut client,
&runner_options,
&client_options,
&logger,
);
let _hurl_log = runner::run(&hurl_file, filename, &mut client, &runner_options, &logger);
}
#[cfg(test)]
@ -168,24 +156,12 @@ fn test_hello() {
}],
line_terminators: vec![],
};
let variables = HashMap::new();
let runner_options = RunnerOptions {
fail_fast: true,
variables,
to_entry: None,
context_dir: ContextDir::default(),
ignore_asserts: false,
very_verbose: false,
pre_entry: None,
post_entry: None,
};
let runner_options = RunnerOptions::default();
runner::run(
&hurl_file,
"filename",
&mut client,
&runner_options,
&client_options,
&logger,
);
}