libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 48509bbce8b78daf86bb1c4e9f774aac3c600ea2
parent 1fb1010919fed0f0adb9927650b598e8a4476cb7
Author: Antoine A <>
Date:   Thu,  2 Jul 2026 13:33:28 +0200

nexus: improve testbench

Diffstat:
MCargo.lock | 66++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mlibeufin-nexus/src/manual.rs | 20+++++++++++++++++---
Mtestbench/Cargo.toml | 2++
Mtestbench/src/main.rs | 42+++++++++++++++++++++++++++++++++++-------
4 files changed, 100 insertions(+), 30 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -334,6 +334,16 @@ dependencies = [ ] [[package]] +name = "bstr" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" +dependencies = [ + "memchr", + "serde_core", +] + +[[package]] name = "bumpalo" version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -535,9 +545,9 @@ dependencies = [ [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -1212,6 +1222,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] name = "h2" version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1767,7 +1790,7 @@ dependencies = [ "futures", "jiff", "pretty_assertions", - "rand 0.10.1", + "rand 0.10.2", "regex", "serde", "serde_json", @@ -1800,7 +1823,7 @@ dependencies = [ "jiff", "pdf-writer", "pretty_assertions", - "rand 0.10.1", + "rand 0.10.2", "rcgen", "reqwest", "reqwest-websocket", @@ -1895,14 +1918,14 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "bitflags 2.13.0", "libc", "plain", - "redox_syscall 0.8.1", + "redox_syscall 0.9.0", ] [[package]] @@ -2478,9 +2501,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", "getrandom 0.4.3", @@ -2556,9 +2579,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" +checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759" dependencies = [ "bitflags 2.13.0", ] @@ -2777,9 +2800,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -3450,7 +3473,7 @@ dependencies = [ "http-body-util", "jiff", "listenfd", - "rand 0.10.1", + "rand 0.10.2", "regex", "serde", "serde_json", @@ -3482,7 +3505,8 @@ dependencies = [ "glob", "indexmap", "jiff", - "rand 0.10.1", + "mimalloc", + "rand 0.10.2", "regex", "serde", "serde_json", @@ -3556,6 +3580,7 @@ dependencies = [ "anyhow", "axum", "clap", + "globset", "http-client", "jiff", "libeufin-bank", @@ -3572,6 +3597,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "walkdir", ] [[package]] @@ -3605,9 +3631,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.52" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e48db7b415311b615f910b3dcaa4557bcd4bf1982379c95c223fd8c2a20e210" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", "num-conv", @@ -4014,7 +4040,7 @@ checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "getrandom 0.4.3", "js-sys", - "rand 0.10.1", + "rand 0.10.2", "serde_core", "wasm-bindgen", ] @@ -4708,9 +4734,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977347db8caa080403f6b6b7c1cda9479a8e869316f7e13a59b19076a40f94e3" +checksum = "5431d5661c32445236631278f27946e444ddafe4684cac70b185272d4f9c52d5" [[package]] name = "zmij" diff --git a/libeufin-nexus/src/manual.rs b/libeufin-nexus/src/manual.rs @@ -28,7 +28,7 @@ use jiff::{Timestamp, tz::TimeZone}; use libeufin_ebics::ebics::rand_ebics_id; use sqlx::PgPool; use taler_macros::EnumMeta; -use tracing::{info, warn}; +use tracing::{error, info, warn}; use zip::write::FileOptions; use crate::{ @@ -112,6 +112,8 @@ impl ManualCmd { info!("{metadata}"); } ManualCmd::Import { sources } => { + let mut nb_total = 0; + let mut nb_error = 0; for source in sources { let xml = if source == "-" { let mut buf = Vec::with_capacity(8 * 1024); @@ -120,8 +122,20 @@ impl ManualCmd { } else { std::fs::read(&source)? }; - let nb = register_camt(db, cfg, &xml).await?; - info!("Imported {nb} transactions from {source}") + nb_total += 1; + match register_camt(db, cfg, &xml).await { + Ok(nb) => { + info!("Imported {nb} transactions from {source}") + } + Err(e) => { + error!("{source} {e}"); + nb_error += 0 + } + } + } + info!("Imported {nb_total} files"); + if nb_error > 0 { + bail!("Failed to import {nb_error} files"); } } ManualCmd::Status { diff --git a/testbench/Cargo.toml b/testbench/Cargo.toml @@ -25,6 +25,8 @@ libeufin-ebisync = { path = "../libeufin-ebisync" } libeufin-ebics = { path = "../libeufin-ebics" } owo-colors = "4.3" tracing-subscriber = "0.3" +globset = "0.4.18" +walkdir = "2.5" [dev-dependencies] serde_json.workspace = true diff --git a/testbench/src/main.rs b/testbench/src/main.rs @@ -17,19 +17,20 @@ * <http://www.gnu.org/licenses/> */ -use std::{fmt::Display, str::FromStr}; +use std::{fmt::Display, path::PathBuf, str::FromStr}; use anyhow::bail; use clap::{Parser, ValueEnum}; +use globset::{Glob, GlobSetBuilder}; use jiff::Timestamp; use libeufin_ebics::keys::{load_bank_keys, load_client_keys}; use libeufin_nexus::config::NexusCfg; use owo_colors::OwoColorize as _; use taler_common::{config::Config, log::taler_logger, types::payto::TransferIbanPayto}; use taler_test_utils::{cli::clap_parse, repl::Repl}; -use testbench::full_cfg; use tracing::Level; use tracing_subscriber::util::SubscriberInitExt as _; +use walkdir::WalkDir; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] enum Component { @@ -100,6 +101,10 @@ pub enum NexusCmd { }, Wss, TxCheck, + Import { + path: PathBuf, + glob: Vec<Glob>, + }, } #[derive(Parser)] @@ -180,10 +185,14 @@ async fn main() -> anyhow::Result<()> { // Augment config let simple_cfg = std::fs::read_to_string(format!("testbench/test/platform/{}.conf", cmd.platform)).unwrap(); - let cfg = full_cfg( - &format!("testbench/test/platform/{}.conf", cmd.platform), - &format!( + let cfg = Config::from_mem_with_env( + match cmd.component { + Component::Nexus => libeufin_nexus::CONFIG_SOURCE, + Component::Ebisync => libeufin_ebisync::config::CONFIG_SOURCE + } + , &format!( r#" + {simple_cfg} {} [paths] LIBEUFIN_NEXUS_HOME = testbench/test/{} @@ -217,8 +226,7 @@ async fn main() -> anyhow::Result<()> { .replace("[nexus-setup]", "[ebisync-setup]"), cmd.platform, cmd.platform - ), - ); + )).unwrap(); let cfg = NexusCfg::parse(&cfg).unwrap(); let ebics = cfg.keys().unwrap(); let (name, settings) = match cfg.host().unwrap().base_url.as_str() { @@ -325,6 +333,26 @@ async fn main() -> anyhow::Result<()> { NexusCmd::Wss => { run(&format!("testing wss {ebics_log}")).await; } + NexusCmd::Import { path, glob } => { + let mut b = GlobSetBuilder::new(); + for glob in glob { + b.add(glob); + } + let matcher = b.build().unwrap(); + let mut paths = Vec::new(); + for entry in WalkDir::new(&path).into_iter().filter_map(Result::ok) { + let entry = entry.path(); + + // usually match against relative path + let rel = entry.strip_prefix(&path).unwrap_or(entry); + + if matcher.is_match(rel) { + paths.push(entry.to_string_lossy().to_string()); + } + } + + run(&format!("manual import {}", paths.join(" "))).await; + } NexusCmd::Exit => break, } } else {