mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-10-26 08:18:26 +03:00
Move Retry to core types.
This commit is contained in:
parent
b83741d9ef
commit
bde10d3102
@ -1,7 +1,6 @@
|
||||
name: retry
|
||||
long: retry
|
||||
value: NUM
|
||||
value_default: 0
|
||||
value_parser: clap::value_parser!(i32).range(-1..)
|
||||
help: Maximum number of retries, 0 for no retries, -1 for unlimited retries
|
||||
---
|
||||
|
@ -26,7 +26,7 @@ def main():
|
||||
+ get_files("tests_failed/*." + extension)
|
||||
+ get_files("tests_failed_not_linted/*." + extension)
|
||||
+ get_files("tests_error_parser/*." + extension)
|
||||
# + get_files("ssl/*." + extension)
|
||||
+ get_files("ssl/*." + extension)
|
||||
)
|
||||
for f in sorted(script_files):
|
||||
test_script.test(f)
|
||||
|
@ -108,7 +108,7 @@ Options:
|
||||
--resolve <HOST:PORT:ADDR>
|
||||
Provide a custom address for a specific HOST and PORT pair
|
||||
--retry <NUM>
|
||||
Maximum number of retries, 0 for no retries, -1 for unlimited retries [default: 0]
|
||||
Maximum number of retries, 0 for no retries, -1 for unlimited retries
|
||||
--retry-interval <MILLISECONDS>
|
||||
Interval in milliseconds before a retry [default: 1000]
|
||||
--ssl-no-revoke
|
||||
|
@ -450,7 +450,6 @@ pub fn retry() -> clap::Arg {
|
||||
clap::Arg::new("retry")
|
||||
.long("retry")
|
||||
.value_name("NUM")
|
||||
.default_value("0")
|
||||
.value_parser(clap::value_parser!(i32).range(-1..))
|
||||
.allow_hyphen_values(true)
|
||||
.help("Maximum number of retries, 0 for no retries, -1 for unlimited retries")
|
||||
|
@ -24,7 +24,7 @@ use std::{env, fs, io};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use hurl::runner::{Input, Value};
|
||||
use hurl_core::ast::Retry;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
use super::variables::{parse as parse_variable, parse_value};
|
||||
use super::{CliOptionsError, Repeat};
|
||||
@ -378,11 +378,11 @@ pub fn resolves(arg_matches: &ArgMatches) -> Vec<String> {
|
||||
get_strings(arg_matches, "resolve").unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn retry(arg_matches: &ArgMatches) -> Retry {
|
||||
match get::<i32>(arg_matches, "retry").unwrap() {
|
||||
-1 => Retry::Infinite,
|
||||
0 => Retry::None,
|
||||
r => Retry::Finite(r as usize),
|
||||
pub fn retry(arg_matches: &ArgMatches) -> Option<Retry> {
|
||||
match get::<i32>(arg_matches, "retry") {
|
||||
Some(-1) => Some(Retry::Infinite),
|
||||
Some(r) => Some(Retry::Finite(r as usize)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,12 @@ use hurl::http::RequestedHttpVersion;
|
||||
use hurl::runner::{Input, Output};
|
||||
use hurl::util::logger::{LoggerOptions, LoggerOptionsBuilder, Verbosity};
|
||||
use hurl::util::path::ContextDir;
|
||||
use hurl_core::ast::{Entry, Retry};
|
||||
use hurl_core::ast::Entry;
|
||||
|
||||
use crate::cli;
|
||||
use crate::runner::{RunnerOptions, RunnerOptionsBuilder, Value};
|
||||
pub use error::CliOptionsError;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
/// Represents the list of all options that can be used in Hurl command line.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -82,7 +83,7 @@ pub struct CliOptions {
|
||||
pub proxy: Option<String>,
|
||||
pub repeat: Option<Repeat>,
|
||||
pub resolves: Vec<String>,
|
||||
pub retry: Retry,
|
||||
pub retry: Option<Retry>,
|
||||
pub retry_interval: Duration,
|
||||
pub ssl_no_revoke: bool,
|
||||
pub tap_file: Option<PathBuf>,
|
||||
|
@ -22,10 +22,11 @@ use std::time::Instant;
|
||||
use chrono::Utc;
|
||||
use hurl_core::ast::VersionValue::VersionAnyLegacy;
|
||||
use hurl_core::ast::{
|
||||
Body, Bytes, Entry, MultilineString, OptionKind, Request, Response, Retry, SourceInfo,
|
||||
Body, Bytes, Entry, MultilineString, OptionKind, Request, Response, SourceInfo,
|
||||
};
|
||||
use hurl_core::error::DisplaySourceError;
|
||||
use hurl_core::parser;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
use crate::http::{Call, Client};
|
||||
use crate::runner::event::EventListener;
|
||||
@ -290,7 +291,7 @@ fn run_request(
|
||||
let mut has_error = !result.errors.is_empty();
|
||||
|
||||
// The retry threshold can only be reached with a finite positive number of retries
|
||||
let retry_max_reached = if let Retry::Finite(r) = options.retry {
|
||||
let retry_max_reached = if let Some(Retry::Finite(r)) = options.retry {
|
||||
retry_count > r
|
||||
} else {
|
||||
false
|
||||
@ -306,7 +307,7 @@ fn run_request(
|
||||
|
||||
// We log eventual errors, only if we're not retrying the current entry...
|
||||
// The retry does not take into account a possible output Error
|
||||
let retry = !matches!(options.retry, Retry::None) && !retry_max_reached && has_error;
|
||||
let retry = options.retry.is_some() && !retry_max_reached && has_error;
|
||||
|
||||
// When --output is overridden on a request level, we output the HTTP response only if the
|
||||
// call has succeeded. Output errors are not taken into account for retrying requests.
|
||||
@ -484,7 +485,11 @@ fn get_non_default_options(options: &RunnerOptions) -> Vec<(&'static str, String
|
||||
}
|
||||
|
||||
if options.retry != default_options.retry {
|
||||
non_default_options.push(("retry", options.retry.to_string()));
|
||||
let value = match options.retry {
|
||||
Some(retry) => retry.to_string(),
|
||||
None => "none".to_string(),
|
||||
};
|
||||
non_default_options.push(("retry", value));
|
||||
}
|
||||
|
||||
if options.unix_socket != default_options.unix_socket {
|
||||
|
@ -20,8 +20,9 @@ use std::time::Duration;
|
||||
|
||||
use hurl_core::ast::{
|
||||
BooleanOption, Entry, EntryOption, Float, NaturalOption, Number as AstNumber, OptionKind,
|
||||
Retry, RetryOption, SectionValue, VariableDefinition, VariableValue,
|
||||
RetryOption, SectionValue, VariableDefinition, VariableValue,
|
||||
};
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
use crate::http::{IpResolve, RequestedHttpVersion};
|
||||
use crate::runner::template::{eval_expression, eval_template};
|
||||
@ -204,7 +205,7 @@ pub fn get_entry_options(
|
||||
}
|
||||
OptionKind::Retry(value) => {
|
||||
let value = eval_retry_option(value, variables)?;
|
||||
entry_options.retry = value;
|
||||
entry_options.retry = Some(value);
|
||||
}
|
||||
OptionKind::RetryInterval(value) => {
|
||||
let value = eval_natural_option(value, variables)?;
|
||||
@ -356,9 +357,7 @@ fn eval_retry_option(
|
||||
Value::Number(Number::Integer(value)) => {
|
||||
if value == -1 {
|
||||
Ok(Retry::Infinite)
|
||||
} else if value == 0 {
|
||||
Ok(Retry::None)
|
||||
} else if value > 0 {
|
||||
} else if value >= 0 {
|
||||
Ok(Retry::Finite(value as usize))
|
||||
} else {
|
||||
let kind = RunnerErrorKind::TemplateVariableInvalidType {
|
||||
|
@ -17,7 +17,8 @@
|
||||
*/
|
||||
use std::time::Duration;
|
||||
|
||||
use hurl_core::ast::{Entry, Retry};
|
||||
use hurl_core::ast::Entry;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
use crate::http::{IpResolve, RequestedHttpVersion};
|
||||
use crate::runner::Output;
|
||||
@ -54,7 +55,7 @@ pub struct RunnerOptionsBuilder {
|
||||
pre_entry: Option<fn(Entry) -> bool>,
|
||||
proxy: Option<String>,
|
||||
resolves: Vec<String>,
|
||||
retry: Retry,
|
||||
retry: Option<Retry>,
|
||||
retry_interval: Duration,
|
||||
skip: bool,
|
||||
ssl_no_revoke: bool,
|
||||
@ -98,7 +99,7 @@ impl Default for RunnerOptionsBuilder {
|
||||
pre_entry: None,
|
||||
proxy: None,
|
||||
resolves: vec![],
|
||||
retry: Retry::None,
|
||||
retry: None,
|
||||
retry_interval: Duration::from_millis(1000),
|
||||
skip: false,
|
||||
ssl_no_revoke: false,
|
||||
@ -327,7 +328,7 @@ impl RunnerOptionsBuilder {
|
||||
/// Sets maximum number of retries.
|
||||
///
|
||||
/// Default is 0.
|
||||
pub fn retry(&mut self, retry: Retry) -> &mut Self {
|
||||
pub fn retry(&mut self, retry: Option<Retry>) -> &mut Self {
|
||||
self.retry = retry;
|
||||
self
|
||||
}
|
||||
@ -461,7 +462,7 @@ pub struct RunnerOptions {
|
||||
pub(crate) pre_entry: Option<fn(Entry) -> bool>,
|
||||
pub(crate) proxy: Option<String>,
|
||||
pub(crate) resolves: Vec<String>,
|
||||
pub(crate) retry: Retry,
|
||||
pub(crate) retry: Option<Retry>,
|
||||
pub(crate) retry_interval: Duration,
|
||||
pub(crate) skip: bool,
|
||||
pub(crate) ssl_no_revoke: bool,
|
||||
|
@ -24,7 +24,6 @@ use hurl::runner;
|
||||
use hurl::runner::{EntryResult, HurlResult, RunnerOptionsBuilder};
|
||||
use hurl::util::logger::LoggerOptionsBuilder;
|
||||
use hurl::util::path::ContextDir;
|
||||
use hurl_core::ast::Retry;
|
||||
|
||||
#[test]
|
||||
fn simple_sample() {
|
||||
@ -117,7 +116,7 @@ fn simple_sample() {
|
||||
.post_entry(None)
|
||||
.pre_entry(None)
|
||||
.proxy(None)
|
||||
.retry(Retry::None)
|
||||
.retry(None)
|
||||
.retry_interval(Duration::from_secs(1))
|
||||
.timeout(Duration::from_secs(300))
|
||||
.to_entry(None)
|
||||
|
@ -16,6 +16,7 @@
|
||||
*
|
||||
*/
|
||||
use crate::ast::json;
|
||||
use crate::typing::Retry;
|
||||
|
||||
///
|
||||
/// Hurl AST
|
||||
@ -915,10 +916,3 @@ pub enum FilterValue {
|
||||
expr: Template,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
|
||||
pub enum Retry {
|
||||
None,
|
||||
Finite(usize),
|
||||
Infinite,
|
||||
}
|
||||
|
@ -278,17 +278,6 @@ impl PredicateFuncValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Retry {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let value = match self {
|
||||
Retry::None => 0,
|
||||
Retry::Finite(n) => *n as i32,
|
||||
Retry::Infinite => -1,
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -18,6 +18,7 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::typing::Retry;
|
||||
|
||||
/// Returns an HTML string of the Hurl file `hurl_file`.
|
||||
///
|
||||
@ -262,7 +263,6 @@ impl HtmlFormatter {
|
||||
match retry {
|
||||
Retry::Finite(n) => self.fmt_number(n),
|
||||
Retry::Infinite => self.fmt_number(-1),
|
||||
Retry::None => self.fmt_number(0),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,3 +20,4 @@ pub mod error;
|
||||
pub mod format;
|
||||
pub mod parser;
|
||||
pub mod text;
|
||||
pub mod typing;
|
||||
|
@ -23,6 +23,7 @@ use crate::parser::primitives::*;
|
||||
use crate::parser::reader::Reader;
|
||||
use crate::parser::string::*;
|
||||
use crate::parser::{expr, filename, filename_password, ParseResult};
|
||||
use crate::typing::Retry;
|
||||
|
||||
/// Parse an option in an `[Options]` section.
|
||||
pub fn parse(reader: &mut Reader) -> ParseResult<EntryOption> {
|
||||
@ -255,9 +256,7 @@ fn retry(reader: &mut Reader) -> ParseResult<Retry> {
|
||||
let value = nonrecover(integer, reader)?;
|
||||
if value == -1 {
|
||||
Ok(Retry::Infinite)
|
||||
} else if value == 0 {
|
||||
Ok(Retry::None)
|
||||
} else if value > 0 {
|
||||
} else if value >= 0 {
|
||||
Ok(Retry::Finite(value as usize))
|
||||
} else {
|
||||
let kind = ParseErrorKind::Expecting {
|
||||
|
36
packages/hurl_core/src/typing/mod.rs
Normal file
36
packages/hurl_core/src/typing/mod.rs
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Hurl (https://hurl.dev)
|
||||
* Copyright (C) 2024 Orange
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
use core::fmt;
|
||||
|
||||
/// Represents a retry operation, either finite or infinite.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
|
||||
pub enum Retry {
|
||||
Finite(usize),
|
||||
Infinite,
|
||||
}
|
||||
|
||||
impl fmt::Display for Retry {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let value = match self {
|
||||
Retry::Finite(n) => *n as i32,
|
||||
Retry::Infinite => -1,
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
use base64::engine::general_purpose;
|
||||
use base64::Engine;
|
||||
use hurl_core::ast::*;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
use super::serialize_json::*;
|
||||
|
||||
@ -363,7 +364,6 @@ impl ToJson for RetryOption {
|
||||
impl ToJson for Retry {
|
||||
fn to_json(&self) -> JValue {
|
||||
match self {
|
||||
Retry::None => JValue::Number("0".to_string()),
|
||||
Retry::Finite(value) => JValue::Number(value.to_string()),
|
||||
Retry::Infinite => JValue::Number("-1".to_string()),
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
*
|
||||
*/
|
||||
use hurl_core::ast::*;
|
||||
use hurl_core::typing::Retry;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Token {
|
||||
@ -945,7 +946,6 @@ impl Tokenizable for RetryOption {
|
||||
impl Tokenizable for Retry {
|
||||
fn tokenize(&self) -> Vec<Token> {
|
||||
match self {
|
||||
Retry::None => vec![Token::Number("0".to_string())],
|
||||
Retry::Finite(n) => vec![Token::Number(n.to_string())],
|
||||
Retry::Infinite => vec![Token::Number("-1".to_string())],
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user