From 2f18340f00f7c0d6134fb049349c7fc49cfbf136 Mon Sep 17 00:00:00 2001 From: Fabrice Reix Date: Wed, 26 May 2021 10:06:29 +0200 Subject: [PATCH] Initialise Error Handler with a native "silent" callback The callback can not be implemented because it needs to be variadic --- Cargo.lock | 5 +++-- integration/tests/error_assert_xpath.exit | 1 + integration/tests/error_assert_xpath.html | 1 + integration/tests/error_assert_xpath.hurl | 4 ++++ integration/tests/error_assert_xpath.json | 1 + integration/tests/error_assert_xpath.py | 6 ++++++ packages/hurl/Cargo.toml | 4 +++- packages/hurl/build.rs | 10 +++++++++ packages/hurl/native/libxml.c | 5 +++++ packages/hurl/src/runner/xpath.rs | 26 ++++++++++++++++++----- 10 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 integration/tests/error_assert_xpath.exit create mode 100644 integration/tests/error_assert_xpath.html create mode 100644 integration/tests/error_assert_xpath.hurl create mode 100644 integration/tests/error_assert_xpath.json create mode 100644 integration/tests/error_assert_xpath.py create mode 100644 packages/hurl/build.rs create mode 100644 packages/hurl/native/libxml.c diff --git a/Cargo.lock b/Cargo.lock index d897f06e0..c73985183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,6 +333,7 @@ dependencies = [ "atty", "base64", "brotli", + "cc", "chrono", "clap", "colored", @@ -419,9 +420,9 @@ checksum = "3286f09f7d4926fc486334f28d8d2e6ebe4f7f9994494b6dab27ddfad2c9b11b" [[package]] name = "libxml" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d529280405174bd6f363d0f8a3086c27e6e60cc0efbc18cf94338f002f461b" +checksum = "496410f67173a59f4e98954c4e7fabe96f6707d46c5f781eb01d96b2703ea6fc" dependencies = [ "libc", "pkg-config", diff --git a/integration/tests/error_assert_xpath.exit b/integration/tests/error_assert_xpath.exit new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/integration/tests/error_assert_xpath.exit @@ -0,0 +1 @@ +4 diff --git a/integration/tests/error_assert_xpath.html b/integration/tests/error_assert_xpath.html new file mode 100644 index 000000000..c4b7370e3 --- /dev/null +++ b/integration/tests/error_assert_xpath.html @@ -0,0 +1 @@ +
GET http://localhost:8000/error-assert-xpath
HTTP/1.0 200[Asserts]xpath "strong(//head/title)" equals "Welcome to Quiz!"
\ No newline at end of file diff --git a/integration/tests/error_assert_xpath.hurl b/integration/tests/error_assert_xpath.hurl new file mode 100644 index 000000000..6589f4368 --- /dev/null +++ b/integration/tests/error_assert_xpath.hurl @@ -0,0 +1,4 @@ +GET http://localhost:8000/error-assert-xpath +HTTP/1.0 200 +[Asserts] +xpath "strong(//head/title)" equals "Welcome to Quiz!" diff --git a/integration/tests/error_assert_xpath.json b/integration/tests/error_assert_xpath.json new file mode 100644 index 000000000..ec8306f49 --- /dev/null +++ b/integration/tests/error_assert_xpath.json @@ -0,0 +1 @@ +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-assert-xpath"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"strong(//head/title)"},"predicate":{"type":"equal","value":"Welcome to Quiz!"}}]}}]} \ No newline at end of file diff --git a/integration/tests/error_assert_xpath.py b/integration/tests/error_assert_xpath.py new file mode 100644 index 000000000..5914831aa --- /dev/null +++ b/integration/tests/error_assert_xpath.py @@ -0,0 +1,6 @@ +from tests import app + +@app.route("/error-assert-xpath") +def error_assert_xpath(): + return 'Test' + diff --git a/packages/hurl/Cargo.toml b/packages/hurl/Cargo.toml index 0d0952b64..3229e2223 100644 --- a/packages/hurl/Cargo.toml +++ b/packages/hurl/Cargo.toml @@ -28,7 +28,7 @@ encoding = "0.2" float-cmp = "0.6.0" hurl_core = { version = "1.1.0", path = "../hurl_core" } libflate = "1.0.2" -libxml = "0.2.12" +libxml = "0.2.17" percent-encoding = "2.1.0" regex = "1.1.0" serde = "1.0.104" @@ -38,6 +38,8 @@ url = "2.1.0" [target.'cfg(unix)'.dependencies] termion = "1.5.5" +[build-dependencies] +cc = "1.0.52" diff --git a/packages/hurl/build.rs b/packages/hurl/build.rs new file mode 100644 index 000000000..cb3793efa --- /dev/null +++ b/packages/hurl/build.rs @@ -0,0 +1,10 @@ +use cc::Build; +use std::path::Path; + +fn main() { + let project_root = Path::new(env!("CARGO_MANIFEST_DIR")); + let native_src = project_root.join("native"); + Build::new() + .file(native_src.join("libxml.c")) + .compile("mylib"); +} diff --git a/packages/hurl/native/libxml.c b/packages/hurl/native/libxml.c new file mode 100644 index 000000000..a6bf1851f --- /dev/null +++ b/packages/hurl/native/libxml.c @@ -0,0 +1,5 @@ +// This callback will prevent from outputting error messages +// It could not be implemented in Rust, because the function is variadic +void silentErrorFunc(void *ctx, const char * msg, ...) +{ +} \ No newline at end of file diff --git a/packages/hurl/src/runner/xpath.rs b/packages/hurl/src/runner/xpath.rs index 131bcbaa2..f0b1c3b52 100644 --- a/packages/hurl/src/runner/xpath.rs +++ b/packages/hurl/src/runner/xpath.rs @@ -17,7 +17,6 @@ */ // unique entry point to libxml -extern crate libxml; use std::ffi::CStr; @@ -61,14 +60,24 @@ pub fn eval_html(html: String, expr: String) -> Result { } } +extern "C" { + pub fn silentErrorFunc( + ctx: *mut ::std::os::raw::c_void, + msg: *const ::std::os::raw::c_char, + ... + ); +} + pub fn eval(doc: libxml::tree::Document, expr: String) -> Result { let context = match libxml::xpath::Context::new(&doc) { Ok(context) => context, _ => panic!("error setting context in xpath module"), }; + unsafe { - libxml::bindings::initGenericErrorDefaultFunc(&mut None); + libxml::bindings::initGenericErrorDefaultFunc(&mut Some(silentErrorFunc)); } + let result = match context.evaluate(expr.as_str()) { Ok(object) => object, Err(_) => return Err(XpathError::Eval {}), @@ -123,7 +132,7 @@ mod tests { assert_eq!(eval_xml(xml.clone(), xpath).unwrap(), Value::from_f64(2.0)); let xpath = String::from("number(//food/banana/@price)"); - assert_eq!(eval_xml(xml.clone(), xpath).unwrap(), Value::from_f64(1.1)); + assert_eq!(eval_xml(xml, xpath).unwrap(), Value::from_f64(1.1)); } #[test] @@ -181,7 +190,7 @@ mod tests { ); let xpath = String::from("normalize-space(/html/head/meta/@charset)"); assert_eq!( - eval_html(html.clone(), xpath).unwrap(), + eval_html(html, xpath).unwrap(), Value::String(String::from("UTF-8")) ); } @@ -191,6 +200,13 @@ mod tests { let html = String::from(r#""#); //let xpath = String::from("boolean(count(//a[contains(@href,'xxx')]))"); let xpath = String::from("boolean(count(//a[contains(@href,'xxx')]))"); - assert_eq!(eval_html(html.clone(), xpath).unwrap(), Value::Bool(false)); + assert_eq!(eval_html(html, xpath).unwrap(), Value::Bool(false)); + } + + #[test] + fn test_unregistered_function() { + let html = String::from(r#""#); + let xpath = String::from("strong(//head/title)"); + assert_eq!(eval_html(html, xpath).err().unwrap(), XpathError::Eval); } }