commit 48509bbce8b78daf86bb1c4e9f774aac3c600ea2
parent 1fb1010919fed0f0adb9927650b598e8a4476cb7
Author: Antoine A <>
Date: Thu, 2 Jul 2026 13:33:28 +0200
nexus: improve testbench
Diffstat:
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 {