From 77ae5078a612618583ab1430ab726999e16789f0 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal <39146854+hansieodendaal@users.noreply.github.com> Date: Mon, 19 Jan 2026 08:48:05 +0200 Subject: [PATCH] feat: refactor for using external cucumber (#6) --- .cargo-deny.toml | 3 +- Cargo.lock | 474 +----------------- Cargo.toml | 5 +- book/src/SUMMARY.md | 1 - book/src/architecture-overview.md | 3 - book/src/ci-integration.md | 54 +- book/src/cucumber-bdd.md | 85 ---- examples/Cargo.toml | 2 - .../features/auto_deployer_smoke.feature | 34 -- .../cucumber/features/compose_smoke.feature | 13 - .../cucumber/features/local_smoke.feature | 14 - examples/src/bin/compose_runner.rs | 5 +- examples/src/bin/cucumber_auto.rs | 66 --- examples/src/bin/cucumber_compose.rs | 12 - examples/src/bin/cucumber_host.rs | 12 - examples/src/bin/local_runner.rs | 3 +- examples/src/defaults.rs | 3 +- examples/src/lib.rs | 7 + .../stack/scripts/docker/build_cfgsync.sh | 2 +- .../{core => configs}/src/constants.rs | 18 +- testing-framework/configs/src/lib.rs | 1 + testing-framework/configs/src/nodes/common.rs | 3 +- .../configs/src/topology/configs/da.rs | 7 +- testing-framework/core/src/kzg.rs | 3 +- testing-framework/core/src/lib.rs | 1 - .../core/src/scenario/cfgsync.rs | 6 +- testing-framework/cucumber/Cargo.toml | 21 - testing-framework/cucumber/src/lib.rs | 4 - testing-framework/cucumber/src/steps/mod.rs | 3 - testing-framework/cucumber/src/steps/run.rs | 72 --- .../cucumber/src/steps/scenario.rs | 31 -- .../cucumber/src/steps/workloads.rs | 52 -- testing-framework/cucumber/src/world.rs | 365 -------------- .../deployers/compose/Cargo.toml | 33 +- .../deployers/compose/src/deployer/mod.rs | 2 +- .../deployers/compose/src/descriptor/mod.rs | 2 +- .../deployers/compose/src/docker/mod.rs | 5 +- .../deployers/compose/src/docker/workspace.rs | 32 +- .../compose/src/infrastructure/environment.rs | 3 +- testing-framework/deployers/k8s/Cargo.toml | 35 +- .../k8s/src/infrastructure/assets.rs | 8 +- .../deployers/k8s/src/lifecycle/wait/mod.rs | 12 +- .../tools/{cfgsync => cfgsync_tf}/Cargo.toml | 2 +- .../src/bin/cfgsync-client.rs | 8 +- .../src/bin/cfgsync-server.rs | 2 +- .../{cfgsync => cfgsync_tf}/src/client.rs | 0 .../src/config/builder.rs | 0 .../{cfgsync => cfgsync_tf}/src/config/kms.rs | 0 .../src/config/providers.rs | 0 .../src/config/tracing.rs | 0 .../src/config/validation.rs | 0 .../tools/{cfgsync => cfgsync_tf}/src/host.rs | 10 +- .../tools/{cfgsync => cfgsync_tf}/src/lib.rs | 0 .../src/network/address.rs | 0 .../src/network/mod.rs | 0 .../src/network/peers.rs | 0 .../tools/{cfgsync => cfgsync_tf}/src/repo.rs | 0 .../{cfgsync => cfgsync_tf}/src/server.rs | 0 58 files changed, 134 insertions(+), 1405 deletions(-) delete mode 100644 book/src/cucumber-bdd.md delete mode 100644 examples/cucumber/features/auto_deployer_smoke.feature delete mode 100644 examples/cucumber/features/compose_smoke.feature delete mode 100644 examples/cucumber/features/local_smoke.feature delete mode 100644 examples/src/bin/cucumber_auto.rs delete mode 100644 examples/src/bin/cucumber_compose.rs delete mode 100644 examples/src/bin/cucumber_host.rs rename testing-framework/{core => configs}/src/constants.rs (86%) delete mode 100644 testing-framework/cucumber/Cargo.toml delete mode 100644 testing-framework/cucumber/src/lib.rs delete mode 100644 testing-framework/cucumber/src/steps/mod.rs delete mode 100644 testing-framework/cucumber/src/steps/run.rs delete mode 100644 testing-framework/cucumber/src/steps/scenario.rs delete mode 100644 testing-framework/cucumber/src/steps/workloads.rs delete mode 100644 testing-framework/cucumber/src/world.rs rename testing-framework/tools/{cfgsync => cfgsync_tf}/Cargo.toml (98%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/bin/cfgsync-client.rs (95%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/bin/cfgsync-server.rs (94%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/client.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/config/builder.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/config/kms.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/config/providers.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/config/tracing.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/config/validation.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/host.rs (91%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/lib.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/network/address.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/network/mod.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/network/peers.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/repo.rs (100%) rename testing-framework/tools/{cfgsync => cfgsync_tf}/src/server.rs (100%) diff --git a/.cargo-deny.toml b/.cargo-deny.toml index 4cb03f9..ab01959 100644 --- a/.cargo-deny.toml +++ b/.cargo-deny.toml @@ -15,6 +15,8 @@ ignore = [ "RUSTSEC-2025-0012", # backoff unmaintained; upstream workspace still relies on it "RUSTSEC-2025-0055", # tracing-subscriber ansi escape issue; upstream dependency "RUSTSEC-2025-0134", # rustls-pemfile unmaintained; transitive via rustls stack + "RUSTSEC-2025-0141", # bincode unmaintained; no safe upgrade available + "RUSTSEC-2026-0002", # lru IterMut soundness issue; pending upstream upgrade ] yanked = "deny" @@ -29,7 +31,6 @@ allow = [ "BSD-2-Clause", "BSD-3-Clause", "BSL-1.0", - "BlueOak-1.0.0", "CC0-1.0", "CDLA-Permissive-2.0", "ISC", diff --git a/Cargo.lock b/Cargo.lock index 36511ac..7ba7d35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,56 +54,12 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - [[package]] name = "anstyle" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", -] - [[package]] name = "anyhow" version = "1.0.100" @@ -918,12 +874,6 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" -[[package]] -name = "bytecount" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" - [[package]] name = "bytemuck" version = "1.24.0" @@ -1012,7 +962,7 @@ dependencies = [ ] [[package]] -name = "cfgsync" +name = "cfgsync_tf" version = "0.1.0" dependencies = [ "anyhow", @@ -1225,11 +1175,8 @@ version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ - "anstream", "anstyle", "clap_lex", - "strsim", - "terminal_size", ] [[package]] @@ -1263,12 +1210,6 @@ dependencies = [ "owo-colors", ] -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - [[package]] name = "common-http-client" version = "0.1.0" @@ -1295,19 +1236,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width", - "windows-sys 0.61.2", -] - [[package]] name = "const-hex" version = "1.17.0" @@ -1341,15 +1269,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -1509,76 +1428,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "cucumber" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c09939b8de21501b829a3839fa8a01ef6cc226e6bc1f5f163f7104bd5e847d" -dependencies = [ - "anyhow", - "clap", - "console", - "cucumber-codegen", - "cucumber-expressions", - "derive_more", - "either", - "futures", - "gherkin", - "globwalk", - "humantime", - "inventory", - "itertools 0.14.0", - "junit-report", - "linked-hash-map", - "pin-project", - "ref-cast", - "regex", - "sealed", - "smart-default", -] - -[[package]] -name = "cucumber-codegen" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f5afe541b5147a7b986816153ccfd502622bb37789420cfff412685f27c0a95" -dependencies = [ - "cucumber-expressions", - "inflections", - "itertools 0.14.0", - "proc-macro2", - "quote", - "regex", - "syn 2.0.111", - "synthez", -] - -[[package]] -name = "cucumber-expressions" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6401038de3af44fe74e6fccdb8a5b7db7ba418f480c8e9ad584c6f65c05a27a6" -dependencies = [ - "derive_more", - "either", - "nom 8.0.0", - "nom_locate", - "regex", - "regex-syntax", -] - -[[package]] -name = "cucumber_ext" -version = "0.1.0" -dependencies = [ - "cucumber", - "testing-framework-core", - "testing-framework-runner-compose", - "testing-framework-runner-local", - "testing-framework-workflows", - "thiserror 2.0.17", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1743,17 +1592,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive-getters" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2c35ab6e03642397cdda1dd58abbc05d418aef8e36297f336d5aba060fe8df" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_arbitrary" version = "1.4.2" @@ -1765,29 +1603,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "derive_more" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" -dependencies = [ - "convert_case 0.10.0", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.111", - "unicode-xid", -] - [[package]] name = "deunicode" version = "1.6.2" @@ -1980,12 +1795,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - [[package]] name = "enum-as-inner" version = "0.6.1" @@ -2369,23 +2178,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gherkin" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70197ce7751bfe8bc828e3a855502d3a869a1e9416b58b10c4bde5cf8a0a3cb3" -dependencies = [ - "heck", - "peg", - "quote", - "serde", - "serde_json", - "syn 2.0.111", - "textwrap", - "thiserror 2.0.17", - "typed-builder", -] - [[package]] name = "gimli" version = "0.32.3" @@ -3156,12 +2948,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "inflections" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" - [[package]] name = "inout" version = "0.1.4" @@ -3180,15 +2966,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "inventory" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" -dependencies = [ - "rustversion", -] - [[package]] name = "ipconfig" version = "0.3.2" @@ -3217,12 +2994,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - [[package]] name = "itertools" version = "0.10.5" @@ -3334,18 +3105,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "junit-report" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c3a3342e6720a82d7d179f380e9841b73a1dd49344e33959fdfe571ce56b55" -dependencies = [ - "derive-getters", - "quick-xml", - "strip-ansi-escapes", - "time", -] - [[package]] name = "k256" version = "0.13.4" @@ -4028,12 +3787,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -4460,17 +4213,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "nom_locate" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b577e2d69827c4740cba2b52efaad1c4cc7c73042860b199710b3575c68438d" -dependencies = [ - "bytecount", - "memchr", - "nom 8.0.0", -] - [[package]] name = "nomos-api" version = "0.1.0" @@ -5302,12 +5044,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - [[package]] name = "openssl" version = "0.10.75" @@ -5471,7 +5207,7 @@ name = "overwatch-derive" version = "0.1.0" source = "git+https://github.com/logos-co/Overwatch?rev=f5a9902#f5a99022f389d65adbd55e51f1e3f9eead62432a" dependencies = [ - "convert_case 0.8.0", + "convert_case", "proc-macro-error2", "proc-macro2", "quote", @@ -5528,33 +5264,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "peg" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" - [[package]] name = "pem" version = "3.0.6" @@ -5971,15 +5680,6 @@ dependencies = [ "unsigned-varint 0.8.0", ] -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" -dependencies = [ - "memchr", -] - [[package]] name = "quinn" version = "0.11.9" @@ -6167,26 +5867,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "ref-cast" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "regex" version = "1.12.2" @@ -6353,8 +6033,6 @@ name = "runner-examples" version = "0.1.0" dependencies = [ "anyhow", - "cucumber", - "cucumber_ext", "testing-framework-core", "testing-framework-runner-compose", "testing-framework-runner-k8s", @@ -6592,17 +6270,6 @@ version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" -[[package]] -name = "sealed" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "sec1" version = "0.7.3" @@ -6910,23 +6577,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "smart-default" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - -[[package]] -name = "smawk" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" - [[package]] name = "snap" version = "1.1.1" @@ -6994,15 +6644,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strip-ansi-escapes" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" -dependencies = [ - "vte", -] - [[package]] name = "strsim" version = "0.11.1" @@ -7091,39 +6732,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "synthez" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d8a928f38f1bc873f28e0d2ba8298ad65374a6ac2241dabd297271531a736cd" -dependencies = [ - "syn 2.0.111", - "synthez-codegen", - "synthez-core", -] - -[[package]] -name = "synthez-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb83b8df4238e11746984dfb3819b155cd270de0e25847f45abad56b3671047" -dependencies = [ - "syn 2.0.111", - "synthez-core", -] - -[[package]] -name = "synthez-core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "906fba967105d822e7c7ed60477b5e76116724d33de68a585681fb253fc30d5c" -dependencies = [ - "proc-macro2", - "quote", - "sealed", - "syn 2.0.111", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -7213,16 +6821,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "terminal_size" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" -dependencies = [ - "rustix", - "windows-sys 0.60.2", -] - [[package]] name = "testing-framework-config" version = "0.1.0" @@ -7312,7 +6910,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "cfgsync", + "cfgsync_tf", "groth16", "key-management-system-service", "nomos-core", @@ -7323,6 +6921,7 @@ dependencies = [ "serde", "tempfile", "tera", + "testing-framework-config", "testing-framework-core", "testing-framework-env", "tests", @@ -7348,6 +6947,7 @@ dependencies = [ "serde", "serde_yaml", "tempfile", + "testing-framework-config", "testing-framework-core", "testing-framework-env", "thiserror 2.0.17", @@ -7440,17 +7040,6 @@ dependencies = [ "tx-service", ] -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" -dependencies = [ - "smawk", - "unicode-linebreak", - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -8043,26 +7632,6 @@ dependencies = [ "utoipa", ] -[[package]] -name = "typed-builder" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda" -dependencies = [ - "typed-builder-macro", -] - -[[package]] -name = "typed-builder-macro" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "typenum" version = "1.19.0" @@ -8105,30 +7674,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - [[package]] name = "unicode-segmentation" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -8171,12 +7722,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - [[package]] name = "utoipa" version = "4.2.3" @@ -8268,15 +7813,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vte" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" -dependencies = [ - "memchr", -] - [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index c29b430..9d8f56d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,11 @@ members = [ "examples/doc-snippets", "testing-framework/configs", "testing-framework/core", - "testing-framework/cucumber", "testing-framework/deployers/compose", "testing-framework/deployers/k8s", "testing-framework/deployers/local", "testing-framework/env", - "testing-framework/tools/cfgsync", + "testing-framework/tools/cfgsync_tf", "testing-framework/workflows", ] resolver = "2" @@ -42,7 +41,7 @@ testing-framework-workflows = { default-features = false, path = "testing-f # Logos git dependencies (pinned to latest master) broadcast-service = { default-features = false, git = "https://github.com/logos-co/nomos-node.git", rev = "1fce2dc3f482c16361316eb2a1b6ccd1206aa917" } -cfgsync = { default-features = false, path = "testing-framework/tools/cfgsync" } +cfgsync_tf = { default-features = false, path = "testing-framework/tools/cfgsync_tf" } chain-leader = { default-features = false, git = "https://github.com/logos-co/nomos-node.git", rev = "1fce2dc3f482c16361316eb2a1b6ccd1206aa917", features = [ "pol-dev-mode", ] } diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index abdea2e..308c148 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -18,7 +18,6 @@ - [Usage Patterns](usage-patterns.md) - [Examples](examples.md) - [Advanced & Artificial Examples](examples-advanced.md) - - [Cucumber/BDD Interface](cucumber-bdd.md) - [Running Scenarios](running-scenarios.md) - [Runners](runners.md) - [RunContext: BlockFeed & Node Control](node-control.md) diff --git a/book/src/architecture-overview.md b/book/src/architecture-overview.md index b7bcae1..6774173 100644 --- a/book/src/architecture-overview.md +++ b/book/src/architecture-overview.md @@ -21,7 +21,6 @@ flowchart TB LocalBin[local_runner.rs] ComposeBin[compose_runner.rs] K8sBin[k8s_runner.rs] - CucumberBin[cucumber_*.rs] end subgraph Workflows["Workflows (Batteries Included)"] @@ -49,7 +48,6 @@ flowchart TB subgraph Support["Supporting Crates"] Configs[Configs & Topology] Nodes[Node API Clients] - Cucumber[Cucumber Extensions] end Examples --> Workflows @@ -96,7 +94,6 @@ flowchart TB **Supporting Crates** - `configs` - Topology configuration and generation - `nodes` - HTTP/RPC client for node APIs -- `cucumber` - BDD/Gherkin integration ### Extension Points diff --git a/book/src/ci-integration.md b/book/src/ci-integration.md index d494a90..8b8d5c2 100644 --- a/book/src/ci-integration.md +++ b/book/src/ci-integration.md @@ -178,58 +178,10 @@ jobs: docker compose down -v 2>/dev/null || true docker ps -a --filter "name=nomos-compose-" -q | xargs -r docker rm -f - # Cucumber/BDD integration tests (if enabled) - cucumber_tests: - name: Cucumber BDD Tests - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Rust toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: nightly - override: true - - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-cucumber-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-cucumber- - - - name: Run Cucumber tests - run: | - # Build prerequisites - scripts/build/build-bundle.sh --platform linux - export NOMOS_BINARIES_TAR=$(ls -t .tmp/nomos-binaries-linux-*.tar.gz | head -1) - - # Run Cucumber tests (host runner) - cargo test -p runner-examples --bin cucumber_host - - - name: Upload test report - if: always() - uses: actions/upload-artifact@v3 - with: - name: cucumber-report - path: | - target/cucumber-reports/ - retention-days: 14 - # Summary job (requires all tests to pass) ci_success: name: CI Success - needs: [host_smoke, compose_matrix, cucumber_tests] + needs: [host_smoke, compose_matrix] runs-on: ubuntu-latest if: always() @@ -237,8 +189,7 @@ jobs: - name: Check all jobs run: | if [[ "${{ needs.host_smoke.result }}" != "success" ]] || \ - [[ "${{ needs.compose_matrix.result }}" != "success" ]] || \ - [[ "${{ needs.cucumber_tests.result }}" != "success" ]]; then + [[ "${{ needs.compose_matrix.result }}" != "success" ]]; then echo "One or more CI jobs failed" exit 1 fi @@ -251,7 +202,6 @@ jobs: 2. **Caching:** Caches Rust dependencies, Docker layers, and nomos-node builds for faster runs 3. **Log Collection:** Automatically uploads logs and artifacts when tests fail 4. **Timeout Protection:** Reasonable timeouts prevent jobs from hanging indefinitely -5. **Cucumber Integration:** Shows how to integrate BDD tests into CI 6. **Clean Teardown:** Ensures Docker resources are cleaned up even on failure ## Customization Points diff --git a/book/src/cucumber-bdd.md b/book/src/cucumber-bdd.md deleted file mode 100644 index d084646..0000000 --- a/book/src/cucumber-bdd.md +++ /dev/null @@ -1,85 +0,0 @@ -# Cucumber/BDD Interface - -The Logos testing repo includes a small Cucumber (Gherkin) harness for “smoke” scenarios. It is useful when you want readable acceptance-style checks, but it intentionally exposes a limited surface area compared to Rust scenarios. - ---- - -## What Exists Today - -- Step definitions live in `testing-framework/cucumber`. -- The runnable entrypoints are binaries in `examples` (crate `runner-examples`): - - `cucumber_host` (local/host deployer) - - `cucumber_compose` (compose deployer) -- Feature files live in `examples/cucumber/features/`. -- Supported deployers: `local` and `compose` (no k8s runner integration in Cucumber yet). - ---- - -## Example Feature (Matches Current Steps) - -This is the shape used by the repo’s smoke features: - -```gherkin -Feature: Testing Framework - Local Runner - - Scenario: Run a local smoke scenario (tx + DA + liveness) - Given deployer is "local" - And topology has 1 validators and 1 executors - And run duration is 60 seconds - And wallets total funds is 1000000000 split across 50 users - And transactions rate is 1 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - And expect consensus liveness - When run scenario - Then scenario should succeed -``` - ---- - -## Running The Smoke Features - -Local runner smoke: - -```bash -POL_PROOF_DEV_MODE=true \ -cargo run -p runner-examples --bin cucumber_host -``` - -Compose runner smoke: - -```bash -POL_PROOF_DEV_MODE=true \ -cargo run -p runner-examples --bin cucumber_compose -``` - ---- - -## Available Steps (Current) - -Topology / runner selection: -- `Given deployer is "local"|"compose"` -- `Given topology has validators and executors` - -Run configuration: -- `Given run duration is seconds` -- `Given wallets total funds is split across users` - -Workloads: -- `Given transactions rate is per block` -- `Given transactions rate is per block using users` -- `Given data availability channel rate is per block and blob rate is per block` - -Expectations: -- `Given expect consensus liveness` -- `Given consensus liveness lag allowance is ` - -Execution + assertion: -- `When run scenario` -- `Then scenario should succeed` - ---- - -## Notes - -- The Cucumber harness builds scenarios using the same core + workflow builder APIs as the Rust examples, so the same prerequisites apply (notably `POL_PROOF_DEV_MODE=true` for practical runs). -- If you need more flexibility (custom workloads/expectations, richer checks, node control/chaos), write Rust scenarios instead: see [Examples](examples.md) and [Extending the Framework](extending.md). diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 82590d5..ba28e95 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -11,8 +11,6 @@ version = "0.1.0" [dependencies] anyhow = "1" -cucumber = { version = "0.22.0" } -cucumber_ext = { path = "../testing-framework/cucumber" } testing-framework-core = { workspace = true } testing-framework-runner-compose = { workspace = true } testing-framework-runner-k8s = { workspace = true } diff --git a/examples/cucumber/features/auto_deployer_smoke.feature b/examples/cucumber/features/auto_deployer_smoke.feature deleted file mode 100644 index e02cff6..0000000 --- a/examples/cucumber/features/auto_deployer_smoke.feature +++ /dev/null @@ -1,34 +0,0 @@ -Feature: Testing Framework - Auto Local/Compose Deployer - - Scenario: Run auto deployer smoke scenario (tx + DA + liveness) - Given we have a CLI deployer specified - And topology has 1 validators and 1 executors - And run duration is 60 seconds - And wallets total funds is 1000000000 split across 50 users - And transactions rate is 1 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - And expect consensus liveness - When run scenario - Then scenario should succeed - - # Note: This test may fail on slow computers - Scenario: Run auto deployer stress smoke scenario (tx + DA + liveness) - Given we have a CLI deployer specified - And topology has 3 validators and 3 executors - And run duration is 120 seconds - And wallets total funds is 1000000000 split across 500 users - And transactions rate is 10 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - And expect consensus liveness - When run scenario - Then scenario should succeed - - Scenario: Run auto deployer stress smoke scenario no liveness (tx + DA + liveness) - Given we have a CLI deployer specified - And topology has 3 validators and 3 executors - And run duration is 120 seconds - And wallets total funds is 1000000000 split across 500 users - And transactions rate is 10 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - When run scenario - Then scenario should succeed diff --git a/examples/cucumber/features/compose_smoke.feature b/examples/cucumber/features/compose_smoke.feature deleted file mode 100644 index d0663e4..0000000 --- a/examples/cucumber/features/compose_smoke.feature +++ /dev/null @@ -1,13 +0,0 @@ -@compose -Feature: Testing Framework - Compose Runner - - Scenario: Run a compose smoke scenario (tx + DA + liveness) - Given deployer is "compose" - And topology has 1 validators and 1 executors - And wallets total funds is 1000 split across 10 users - And run duration is 60 seconds - And transactions rate is 1 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - And expect consensus liveness - When run scenario - Then scenario should succeed diff --git a/examples/cucumber/features/local_smoke.feature b/examples/cucumber/features/local_smoke.feature deleted file mode 100644 index f66630b..0000000 --- a/examples/cucumber/features/local_smoke.feature +++ /dev/null @@ -1,14 +0,0 @@ -@local -Feature: Testing Framework - Local Runner - - Scenario: Run a local smoke scenario (tx + DA + liveness) - Given deployer is "local" - And topology has 1 validators and 1 executors - And run duration is 60 seconds - And wallets total funds is 1000000000 split across 50 users - And transactions rate is 1 per block - And data availability channel rate is 1 per block and blob rate is 1 per block - And expect consensus liveness - When run scenario - Then scenario should succeed - diff --git a/examples/src/bin/compose_runner.rs b/examples/src/bin/compose_runner.rs index e11365d..c0a491f 100644 --- a/examples/src/bin/compose_runner.rs +++ b/examples/src/bin/compose_runner.rs @@ -1,8 +1,9 @@ use std::{process, time::Duration}; use anyhow::{Context as _, Result}; -use cucumber_ext::DeployerKind; -use runner_examples::{ChaosBuilderExt as _, ScenarioBuilderExt as _, demo, read_env_any}; +use runner_examples::{ + ChaosBuilderExt as _, DeployerKind, ScenarioBuilderExt as _, demo, read_env_any, +}; use testing_framework_core::scenario::{Deployer as _, Runner, ScenarioBuilder}; use testing_framework_runner_compose::{ComposeDeployer, ComposeRunnerError}; use tracing::{info, warn}; diff --git a/examples/src/bin/cucumber_auto.rs b/examples/src/bin/cucumber_auto.rs deleted file mode 100644 index 29caaec..0000000 --- a/examples/src/bin/cucumber_auto.rs +++ /dev/null @@ -1,66 +0,0 @@ -/// Usage: Set the environment variable CUCUMBER_DEPLOYER_COMPOSE to use the -/// Compose deployer. Otherwise, the Local deployer is used by default. -/// -/// Example using docker compose deployer: -/// ```sh -/// CUCUMBER_DEPLOYER_COMPOSE=1 cargo run -p runner-examples --bin cucumber_auto -- --name "Run auto deployer smoke scenario" -/// ``` -/// Example using local deployer: -/// ```sh -/// cargo run -p runner-examples --bin cucumber_auto -- --name "Run auto deployer smoke scenario" -/// ``` -use std::{fs, io}; - -use cucumber::{World, WriterExt, writer, writer::Verbosity}; -use cucumber_ext::{DeployerKind, TestingFrameworkWorld}; -use runner_examples::defaults::{init_logging_defaults, init_node_log_dir_defaults, init_tracing}; - -#[tokio::main] -async fn main() { - println!("args: {:?}", std::env::args()); - - let deployer = if std::env::var("CUCUMBER_DEPLOYER_COMPOSE").ok().is_some() { - DeployerKind::Compose - } else { - DeployerKind::Local - }; - println!("Running with '{:?}'", deployer); - - init_logging_defaults(); - init_node_log_dir_defaults(deployer); - init_tracing(); - - // Print current directory for debugging - if let Ok(current_dir) = std::env::current_dir() { - println!("Current directory: {:?}", current_dir); - } - - let file = fs::File::create("cucumber-output-junit.xml").unwrap(); - let world = TestingFrameworkWorld::cucumber() - .repeat_failed() - // following config needed to use eprint statements in the tests - .max_concurrent_scenarios(1) - .fail_on_skipped() - .fail_fast() - .with_writer( - writer::Summarize::new(writer::Basic::new( - io::stdout(), - writer::Coloring::Auto, - Verbosity::ShowWorldAndDocString, - )) - .tee::(writer::JUnit::for_tee(file, 0)) - .normalized(), - ) - .before(move |feature, _rule, scenario, world| { - Box::pin(async move { - println!( - "\nStarting '{}' : '{}' : '{}'\n", - feature.name, scenario.keyword, scenario.name - ); // This will be printed into the stdout_buffer - if let Err(e) = world.set_deployer(deployer) { - panic!("Failed to set deployer: {}", e); - } - }) - }); - world.run_and_exit("examples/cucumber/features/").await; -} diff --git a/examples/src/bin/cucumber_compose.rs b/examples/src/bin/cucumber_compose.rs deleted file mode 100644 index 30a1939..0000000 --- a/examples/src/bin/cucumber_compose.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cucumber::World; -use cucumber_ext::{DeployerKind, TestingFrameworkWorld}; -use runner_examples::defaults::{init_logging_defaults, init_node_log_dir_defaults, init_tracing}; - -#[tokio::main] -async fn main() { - init_logging_defaults(); - init_node_log_dir_defaults(DeployerKind::Compose); - init_tracing(); - - TestingFrameworkWorld::run("examples/cucumber/features/compose_smoke.feature").await; -} diff --git a/examples/src/bin/cucumber_host.rs b/examples/src/bin/cucumber_host.rs deleted file mode 100644 index e00d353..0000000 --- a/examples/src/bin/cucumber_host.rs +++ /dev/null @@ -1,12 +0,0 @@ -use cucumber::World; -use cucumber_ext::{DeployerKind, TestingFrameworkWorld}; -use runner_examples::defaults::{init_logging_defaults, init_node_log_dir_defaults, init_tracing}; - -#[tokio::main] -async fn main() { - init_logging_defaults(); - init_node_log_dir_defaults(DeployerKind::Local); - init_tracing(); - - TestingFrameworkWorld::run("examples/cucumber/features/local_smoke.feature").await; -} diff --git a/examples/src/bin/local_runner.rs b/examples/src/bin/local_runner.rs index 8caca26..981f178 100644 --- a/examples/src/bin/local_runner.rs +++ b/examples/src/bin/local_runner.rs @@ -1,8 +1,7 @@ use std::{env, process, time::Duration}; use anyhow::{Context as _, Result}; -use cucumber_ext::DeployerKind; -use runner_examples::{ScenarioBuilderExt as _, demo, read_env_any}; +use runner_examples::{DeployerKind, ScenarioBuilderExt as _, demo, read_env_any}; use testing_framework_core::scenario::{Deployer as _, Runner, ScenarioBuilder}; use testing_framework_runner_local::LocalDeployer; use tracing::{info, warn}; diff --git a/examples/src/defaults.rs b/examples/src/defaults.rs index 10c03cd..75b5a41 100644 --- a/examples/src/defaults.rs +++ b/examples/src/defaults.rs @@ -3,9 +3,10 @@ use std::{ path::{Path, PathBuf}, }; -use cucumber_ext::DeployerKind; use tracing_subscriber::{EnvFilter, fmt}; +use crate::DeployerKind; + const DEFAULT_NODE_LOG_DIR_REL: &str = ".tmp/node-logs"; const DEFAULT_CONTAINER_NODE_LOG_DIR: &str = "/tmp/node-logs"; diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 5792838..7512183 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -4,3 +4,10 @@ pub mod env; pub use env::read_env_any; pub use testing_framework_workflows::{ChaosBuilderExt, ScenarioBuilderExt}; + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub enum DeployerKind { + #[default] + Local, + Compose, +} diff --git a/testing-framework/assets/stack/scripts/docker/build_cfgsync.sh b/testing-framework/assets/stack/scripts/docker/build_cfgsync.sh index e760250..bea43b4 100755 --- a/testing-framework/assets/stack/scripts/docker/build_cfgsync.sh +++ b/testing-framework/assets/stack/scripts/docker/build_cfgsync.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -cargo build --all-features --manifest-path /workspace/testing-framework/tools/cfgsync/Cargo.toml --bins +cargo build --all-features --manifest-path /workspace/testing-framework/tools/cfgsync_tf/Cargo.toml --bins cp /workspace/target/debug/cfgsync-server /workspace/artifacts/cfgsync-server cp /workspace/target/debug/cfgsync-client /workspace/artifacts/cfgsync-client diff --git a/testing-framework/core/src/constants.rs b/testing-framework/configs/src/constants.rs similarity index 86% rename from testing-framework/core/src/constants.rs rename to testing-framework/configs/src/constants.rs index 9c93984..c7bb153 100644 --- a/testing-framework/core/src/constants.rs +++ b/testing-framework/configs/src/constants.rs @@ -5,12 +5,6 @@ use testing_framework_env as tf_env; /// Default cfgsync port used across runners. pub const DEFAULT_CFGSYNC_PORT: u16 = 4400; -/// Default container path for KZG parameters (compose/k8s mount point). -pub const DEFAULT_KZG_CONTAINER_PATH: &str = "/kzgrs_test_params/kzgrs_test_params"; - -/// Default host-relative directory for KZG assets. -pub const DEFAULT_KZG_HOST_DIR: &str = "testing-framework/assets/stack/kzgrs_test_params"; - /// Default HTTP probe interval used across readiness checks. pub const DEFAULT_HTTP_POLL_INTERVAL: Duration = Duration::from_secs(1); @@ -36,15 +30,25 @@ pub const DEFAULT_LIBP2P_NETWORK_PORT: u16 = 3000; pub const DEFAULT_DA_NETWORK_PORT: u16 = 3300; /// Default blend network port. -pub const DEFAULT_BLEND_NETWORK_PORT: u16 = 4401; +pub const DEFAULT_BLEND_NETWORK_PORT: u16 = 3400; //4401; /// Resolve cfgsync port from `NOMOS_CFGSYNC_PORT`, falling back to the default. pub fn cfgsync_port() -> u16 { tf_env::nomos_cfgsync_port().unwrap_or(DEFAULT_CFGSYNC_PORT) } +/// Default KZG parameters file name. +pub const KZG_PARAMS_FILENAME: &str = "kzgrs_test_params"; +/// Default container path for KZG parameters (compose/k8s mount point). +pub const DEFAULT_KZG_CONTAINER_PATH: &str = "/kzgrs_test_params/kzgrs_test_params"; + /// Resolve container KZG path from `NOMOS_KZG_CONTAINER_PATH`, falling back to /// the default. pub fn kzg_container_path() -> String { tf_env::nomos_kzg_container_path().unwrap_or_else(|| DEFAULT_KZG_CONTAINER_PATH.to_string()) } + +/// Default stack assets directory. +pub const DEFAULT_ASSETS_STACK_DIR: &str = "testing-framework/assets/stack"; +/// Default host-relative directory for KZG assets. +pub const DEFAULT_KZG_HOST_DIR: &str = "testing-framework/assets/stack/kzgrs_test_params"; diff --git a/testing-framework/configs/src/lib.rs b/testing-framework/configs/src/lib.rs index e975e01..0cc15c3 100644 --- a/testing-framework/configs/src/lib.rs +++ b/testing-framework/configs/src/lib.rs @@ -4,6 +4,7 @@ use nomos_core::sdp::ProviderId; use nomos_libp2p::{Multiaddr, PeerId, multiaddr}; use testing_framework_env as tf_env; +pub mod constants; pub mod nodes; pub mod timeouts; pub mod topology; diff --git a/testing-framework/configs/src/nodes/common.rs b/testing-framework/configs/src/nodes/common.rs index ab398ca..ee44133 100644 --- a/testing-framework/configs/src/nodes/common.rs +++ b/testing-framework/configs/src/nodes/common.rs @@ -32,7 +32,7 @@ use nomos_node::{ use nomos_utils::math::NonNegativeF64; use nomos_wallet::WalletServiceSettings; -use crate::{timeouts, topology::configs::GeneralConfig}; +use crate::{constants::KZG_PARAMS_FILENAME, timeouts, topology::configs::GeneralConfig}; // Configuration constants const CRYPTARCHIA_GOSSIPSUB_PROTOCOL: &str = "/cryptarchia/proto"; @@ -45,7 +45,6 @@ const API_RATE_LIMIT_PER_SECOND: u64 = 10000; const API_RATE_LIMIT_BURST: u32 = 10000; const API_MAX_CONCURRENT_REQUESTS: usize = 1000; const BLOB_STORAGE_DIR: &str = "./"; -const KZG_PARAMS_FILENAME: &str = "kzgrs_test_params"; pub(crate) fn cryptarchia_deployment(config: &GeneralConfig) -> CryptarchiaDeploymentSettings { CryptarchiaDeploymentSettings { diff --git a/testing-framework/configs/src/topology/configs/da.rs b/testing-framework/configs/src/topology/configs/da.rs index 8a136dc..43489de 100644 --- a/testing-framework/configs/src/topology/configs/da.rs +++ b/testing-framework/configs/src/topology/configs/da.rs @@ -22,7 +22,7 @@ use testing_framework_env as tf_env; use thiserror::Error; use tracing::warn; -use crate::secret_key_to_peer_id; +use crate::{constants::DEFAULT_KZG_HOST_DIR, secret_key_to_peer_id}; pub static GLOBAL_PARAMS_PATH: LazyLock = LazyLock::new(resolve_global_params_path); @@ -69,7 +69,10 @@ fn resolve_global_params_path() -> String { .unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR"))); let params_path = canonicalize_params_path( - workspace_root.join("testing-framework/assets/stack/kzgrs_test_params"), + workspace_root.join( + testing_framework_env::nomos_kzg_dir_rel() + .unwrap_or_else(|| DEFAULT_KZG_HOST_DIR.to_string()), + ), ); match params_path.canonicalize() { Ok(path) => path.to_string_lossy().to_string(), diff --git a/testing-framework/core/src/kzg.rs b/testing-framework/core/src/kzg.rs index 645b0f3..4b617ef 100644 --- a/testing-framework/core/src/kzg.rs +++ b/testing-framework/core/src/kzg.rs @@ -1,9 +1,8 @@ use std::path::{Path, PathBuf}; +use testing_framework_config::constants::{DEFAULT_KZG_CONTAINER_PATH, DEFAULT_KZG_HOST_DIR}; use testing_framework_env as tf_env; -use crate::constants::{DEFAULT_KZG_CONTAINER_PATH, DEFAULT_KZG_HOST_DIR}; - /// Default in-image path for KZG params used by testnet images. pub const DEFAULT_IN_IMAGE_KZG_PARAMS_PATH: &str = "/opt/nomos/kzg-params/kzgrs_test_params"; diff --git a/testing-framework/core/src/lib.rs b/testing-framework/core/src/lib.rs index db604f4..672df4c 100644 --- a/testing-framework/core/src/lib.rs +++ b/testing-framework/core/src/lib.rs @@ -1,4 +1,3 @@ -pub mod constants; pub mod kzg; pub mod nodes; pub mod scenario; diff --git a/testing-framework/core/src/scenario/cfgsync.rs b/testing-framework/core/src/scenario/cfgsync.rs index 9aac347..43dc888 100644 --- a/testing-framework/core/src/scenario/cfgsync.rs +++ b/testing-framework/core/src/scenario/cfgsync.rs @@ -6,12 +6,10 @@ use nomos_tracing_service::TracingSettings; use nomos_utils::bounded_duration::{MinimalBoundedDuration, SECOND}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; +use testing_framework_config::constants::kzg_container_path; use tracing::debug; -use crate::{ - constants::kzg_container_path, - topology::{configs::wallet::WalletConfig, generation::GeneratedTopology}, -}; +use crate::topology::{configs::wallet::WalletConfig, generation::GeneratedTopology}; #[serde_as] #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/testing-framework/cucumber/Cargo.toml b/testing-framework/cucumber/Cargo.toml deleted file mode 100644 index de7cef4..0000000 --- a/testing-framework/cucumber/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -categories.workspace = true -description.workspace = true -edition.workspace = true -keywords.workspace = true -license.workspace = true -name = "cucumber_ext" -readme.workspace = true -repository.workspace = true -version.workspace = true - -[dependencies] -cucumber = { version = "0.22.0", features = ["default", "macros", "output-junit"] } -testing-framework-core = { workspace = true } -testing-framework-runner-compose = { workspace = true } -testing-framework-runner-local = { workspace = true } -testing-framework-workflows = { workspace = true } -thiserror = { workspace = true } - -[lints] -workspace = true diff --git a/testing-framework/cucumber/src/lib.rs b/testing-framework/cucumber/src/lib.rs deleted file mode 100644 index 7ddfc6e..0000000 --- a/testing-framework/cucumber/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod steps; -mod world; - -pub use world::{DeployerKind, TestingFrameworkWorld}; diff --git a/testing-framework/cucumber/src/steps/mod.rs b/testing-framework/cucumber/src/steps/mod.rs deleted file mode 100644 index 8c3581a..0000000 --- a/testing-framework/cucumber/src/steps/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod run; -mod scenario; -mod workloads; diff --git a/testing-framework/cucumber/src/steps/run.rs b/testing-framework/cucumber/src/steps/run.rs deleted file mode 100644 index 888039b..0000000 --- a/testing-framework/cucumber/src/steps/run.rs +++ /dev/null @@ -1,72 +0,0 @@ -use cucumber::{then, when}; -use testing_framework_core::scenario::Deployer as _; -use testing_framework_runner_compose::ComposeDeployer; -use testing_framework_runner_local::LocalDeployer; - -use crate::world::{DeployerKind, StepError, StepResult, TestingFrameworkWorld}; - -#[when(expr = "run scenario")] -async fn run_scenario(world: &mut TestingFrameworkWorld) -> StepResult { - let deployer = world.deployer.ok_or(StepError::MissingDeployer)?; - world.run.result = Some(match deployer { - DeployerKind::Local => { - let mut scenario = world.build_local_scenario()?; - let deployer = LocalDeployer::default().with_membership_check(world.membership_check); - let result = async { - let runner = - deployer - .deploy(&scenario) - .await - .map_err(|e| StepError::RunFailed { - message: format!("local deploy failed: {e}"), - })?; - runner - .run(&mut scenario) - .await - .map_err(|e| StepError::RunFailed { - message: format!("scenario run failed: {e}"), - })?; - Ok::<(), StepError>(()) - } - .await; - - result.map_err(|e| e.to_string()) - } - DeployerKind::Compose => { - let mut scenario = world.build_compose_scenario()?; - let deployer = ComposeDeployer::default().with_readiness(world.readiness_checks); - let result = async { - let runner = - deployer - .deploy(&scenario) - .await - .map_err(|e| StepError::RunFailed { - message: format!("compose deploy failed: {e}"), - })?; - runner - .run(&mut scenario) - .await - .map_err(|e| StepError::RunFailed { - message: format!("scenario run failed: {e}"), - })?; - Ok::<(), StepError>(()) - } - .await; - - result.map_err(|e| e.to_string()) - } - }); - - Ok(()) -} - -#[then(expr = "scenario should succeed")] -async fn scenario_should_succeed(world: &mut TestingFrameworkWorld) -> StepResult { - match world.run.result.take() { - Some(Ok(())) => Ok(()), - Some(Err(message)) => Err(StepError::RunFailed { message }), - None => Err(StepError::RunFailed { - message: "scenario was not run".to_owned(), - }), - } -} diff --git a/testing-framework/cucumber/src/steps/scenario.rs b/testing-framework/cucumber/src/steps/scenario.rs deleted file mode 100644 index 227f4e3..0000000 --- a/testing-framework/cucumber/src/steps/scenario.rs +++ /dev/null @@ -1,31 +0,0 @@ -use cucumber::given; - -use crate::world::{NetworkKind, StepError, StepResult, TestingFrameworkWorld, parse_deployer}; - -#[given(expr = "deployer is {string}")] -async fn deployer_is(world: &mut TestingFrameworkWorld, deployer: String) -> StepResult { - world.set_deployer(parse_deployer(&deployer)?) -} - -#[given(expr = "we have a CLI deployer specified")] -async fn auto_deployer(world: &mut TestingFrameworkWorld) -> StepResult { - let _unused = world - .deployer - .ok_or(StepError::MissingDeployer) - .inspect_err(|e| { - println!( - "CLI deployer mode not specified, use '--deployer=compose' or '--deployer=local': {}", - e - ) - })?; - Ok(()) -} - -#[given(expr = "topology has {int} validators and {int} executors")] -async fn topology_has( - world: &mut TestingFrameworkWorld, - validators: usize, - executors: usize, -) -> StepResult { - world.set_topology(validators, executors, NetworkKind::Star) -} diff --git a/testing-framework/cucumber/src/steps/workloads.rs b/testing-framework/cucumber/src/steps/workloads.rs deleted file mode 100644 index af2672c..0000000 --- a/testing-framework/cucumber/src/steps/workloads.rs +++ /dev/null @@ -1,52 +0,0 @@ -use cucumber::given; - -use crate::world::{StepResult, TestingFrameworkWorld}; - -#[given(expr = "wallets total funds is {int} split across {int} users")] -async fn wallets_total_funds( - world: &mut TestingFrameworkWorld, - total_funds: u64, - users: usize, -) -> StepResult { - world.set_wallets(total_funds, users) -} - -#[given(expr = "run duration is {int} seconds")] -async fn run_duration(world: &mut TestingFrameworkWorld, seconds: u64) -> StepResult { - world.set_run_duration(seconds) -} - -#[given(expr = "transactions rate is {int} per block")] -async fn tx_rate(world: &mut TestingFrameworkWorld, rate: u64) -> StepResult { - world.set_transactions_rate(rate, None) -} - -#[given(expr = "transactions rate is {int} per block using {int} users")] -async fn tx_rate_with_users( - world: &mut TestingFrameworkWorld, - rate: u64, - users: usize, -) -> StepResult { - world.set_transactions_rate(rate, Some(users)) -} - -#[given( - expr = "data availability channel rate is {int} per block and blob rate is {int} per block" -)] -async fn da_rates( - world: &mut TestingFrameworkWorld, - channel_rate: u64, - blob_rate: u64, -) -> StepResult { - world.set_data_availability_rates(channel_rate, blob_rate) -} - -#[given(expr = "expect consensus liveness")] -async fn expect_consensus_liveness(world: &mut TestingFrameworkWorld) -> StepResult { - world.enable_consensus_liveness() -} - -#[given(expr = "consensus liveness lag allowance is {int}")] -async fn liveness_lag_allowance(world: &mut TestingFrameworkWorld, blocks: u64) -> StepResult { - world.set_consensus_liveness_lag_allowance(blocks) -} diff --git a/testing-framework/cucumber/src/world.rs b/testing-framework/cucumber/src/world.rs deleted file mode 100644 index 2b29c87..0000000 --- a/testing-framework/cucumber/src/world.rs +++ /dev/null @@ -1,365 +0,0 @@ -use std::{env, path::PathBuf, time::Duration}; - -use cucumber::World; -use testing_framework_core::scenario::{ - Builder, NodeControlCapability, Scenario, ScenarioBuildError, ScenarioBuilder, -}; -use testing_framework_workflows::{ScenarioBuilderExt as _, expectations::ConsensusLiveness}; -use thiserror::Error; - -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub enum DeployerKind { - #[default] - Local, - Compose, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum NetworkKind { - Star, -} - -#[derive(Debug, Default, Clone)] -pub struct RunState { - pub result: Option>, -} - -#[derive(Debug, Default, Clone, Copy)] -pub struct ScenarioSpec { - pub topology: Option, - pub duration_secs: Option, - pub wallets: Option, - pub transactions: Option, - pub data_availability: Option, - pub consensus_liveness: Option, -} - -#[derive(Debug, Clone, Copy)] -pub struct TopologySpec { - pub validators: usize, - pub executors: usize, - pub network: NetworkKind, -} - -#[derive(Debug, Clone, Copy)] -pub struct WalletSpec { - pub total_funds: u64, - pub users: usize, -} - -#[derive(Debug, Clone, Copy)] -pub struct TransactionSpec { - pub rate_per_block: u64, - pub users: Option, -} - -#[derive(Debug, Clone, Copy)] -pub struct DataAvailabilitySpec { - pub channel_rate_per_block: u64, - pub blob_rate_per_block: u64, -} - -#[derive(Debug, Clone, Copy)] -pub struct ConsensusLivenessSpec { - pub lag_allowance: Option, -} - -#[derive(Debug, Error)] -pub enum StepError { - #[error("deployer is not selected; set it first (e.g. `Given deployer is \"local\"`)")] - MissingDeployer, - #[error("scenario topology is not configured")] - MissingTopology, - #[error("scenario run duration is not configured")] - MissingRunDuration, - #[error("unsupported deployer kind: {value}")] - UnsupportedDeployer { value: String }, - #[error("step requires deployer {expected:?}, but current deployer is {actual:?}")] - DeployerMismatch { - expected: DeployerKind, - actual: DeployerKind, - }, - #[error("invalid argument: {message}")] - InvalidArgument { message: String }, - #[error("{message}")] - Preflight { message: String }, - #[error("failed to build scenario: {source}")] - ScenarioBuild { - #[source] - source: ScenarioBuildError, - }, - #[error("{message}")] - RunFailed { message: String }, -} - -pub type StepResult = Result<(), StepError>; - -#[derive(World, Debug, Default)] -pub struct TestingFrameworkWorld { - pub deployer: Option, - pub spec: ScenarioSpec, - pub run: RunState, - pub membership_check: bool, - pub readiness_checks: bool, -} - -impl TestingFrameworkWorld { - pub fn set_deployer(&mut self, kind: DeployerKind) -> StepResult { - self.deployer = Some(kind); - Ok(()) - } - - pub fn set_topology( - &mut self, - validators: usize, - executors: usize, - network: NetworkKind, - ) -> StepResult { - self.spec.topology = Some(TopologySpec { - validators: positive_usize("validators", validators)?, - executors, - network, - }); - Ok(()) - } - - pub fn set_run_duration(&mut self, seconds: u64) -> StepResult { - self.spec.duration_secs = Some(positive_u64("duration", seconds)?); - Ok(()) - } - - pub fn set_wallets(&mut self, total_funds: u64, users: usize) -> StepResult { - self.spec.wallets = Some(WalletSpec { - total_funds, - users: positive_usize("wallet users", users)?, - }); - Ok(()) - } - - pub fn set_transactions_rate( - &mut self, - rate_per_block: u64, - users: Option, - ) -> StepResult { - if self.spec.transactions.is_some() { - return Err(StepError::InvalidArgument { - message: "transactions workload already configured".to_owned(), - }); - } - - if users.is_some_and(|u| u == 0) { - return Err(StepError::InvalidArgument { - message: "transactions users must be > 0".to_owned(), - }); - } - - self.spec.transactions = Some(TransactionSpec { - rate_per_block: positive_u64("transactions rate", rate_per_block)?, - users, - }); - Ok(()) - } - - pub fn set_data_availability_rates( - &mut self, - channel_rate_per_block: u64, - blob_rate_per_block: u64, - ) -> StepResult { - if self.spec.data_availability.is_some() { - return Err(StepError::InvalidArgument { - message: "data availability workload already configured".to_owned(), - }); - } - - self.spec.data_availability = Some(DataAvailabilitySpec { - channel_rate_per_block: positive_u64("DA channel rate", channel_rate_per_block)?, - blob_rate_per_block: positive_u64("DA blob rate", blob_rate_per_block)?, - }); - - Ok(()) - } - - pub fn enable_consensus_liveness(&mut self) -> StepResult { - if self.spec.consensus_liveness.is_none() { - self.spec.consensus_liveness = Some(ConsensusLivenessSpec { - lag_allowance: None, - }); - } - - Ok(()) - } - - pub fn set_consensus_liveness_lag_allowance(&mut self, blocks: u64) -> StepResult { - let blocks = positive_u64("lag allowance", blocks)?; - - self.spec.consensus_liveness = Some(ConsensusLivenessSpec { - lag_allowance: Some(blocks), - }); - - Ok(()) - } - - pub fn build_local_scenario(&self) -> Result, StepError> { - self.preflight(DeployerKind::Local)?; - let builder = self.make_builder_for_deployer::<()>(DeployerKind::Local)?; - builder - .build() - .map_err(|source| StepError::ScenarioBuild { source }) - } - - pub fn build_compose_scenario(&self) -> Result, StepError> { - self.preflight(DeployerKind::Compose)?; - let builder = - self.make_builder_for_deployer::(DeployerKind::Compose)?; - builder - .build() - .map_err(|source| StepError::ScenarioBuild { source }) - } - - pub fn preflight(&self, expected: DeployerKind) -> Result<(), StepError> { - let actual = self.deployer.ok_or(StepError::MissingDeployer)?; - if actual != expected { - return Err(StepError::DeployerMismatch { expected, actual }); - } - - if !is_truthy_env("POL_PROOF_DEV_MODE") { - return Err(StepError::Preflight { - message: - "POL_PROOF_DEV_MODE must be set to \"true\" (or \"1\") for practical test runs." - .to_owned(), - }); - } - - if expected == DeployerKind::Local { - let node_ok = env::var_os("NOMOS_NODE_BIN") - .map(PathBuf::from) - .is_some_and(|p| p.is_file()) - || shared_host_bin_path("nomos-node").is_file(); - - let requires_executor_bin = self - .spec - .topology - .is_some_and(|topology| topology.executors > 0); - - let exec_ok = if requires_executor_bin { - env::var_os("NOMOS_EXECUTOR_BIN") - .map(PathBuf::from) - .is_some_and(|p| p.is_file()) - || shared_host_bin_path("nomos-executor").is_file() - } else { - true - }; - - if !(node_ok && exec_ok) { - return Err(StepError::Preflight { - message: "Missing Logos host binaries. Set NOMOS_NODE_BIN (and NOMOS_EXECUTOR_BIN if your scenario uses executors), or run `scripts/run/run-examples.sh host` to restore them into `testing-framework/assets/stack/bin`.".to_owned(), - }); - } - } - - Ok(()) - } - - fn make_builder_for_deployer( - &self, - expected: DeployerKind, - ) -> Result, StepError> { - let actual = self.deployer.ok_or(StepError::MissingDeployer)?; - if actual != expected { - return Err(StepError::DeployerMismatch { expected, actual }); - } - - let topology = self.spec.topology.ok_or(StepError::MissingTopology)?; - let duration_secs = self - .spec - .duration_secs - .ok_or(StepError::MissingRunDuration)?; - - let mut builder: Builder = make_builder(topology).with_capabilities(Caps::default()); - - builder = builder.with_run_duration(Duration::from_secs(duration_secs)); - - if let Some(wallets) = self.spec.wallets { - builder = builder.initialize_wallet(wallets.total_funds, wallets.users); - } - - if let Some(tx) = self.spec.transactions { - builder = builder.transactions_with(|flow| { - let mut flow = flow.rate(tx.rate_per_block); - if let Some(users) = tx.users { - flow = flow.users(users); - } - flow - }); - } - - if let Some(da) = self.spec.data_availability { - builder = builder.da_with(|flow| { - flow.channel_rate(da.channel_rate_per_block) - .blob_rate(da.blob_rate_per_block) - }); - } - - if let Some(liveness) = self.spec.consensus_liveness { - if let Some(lag) = liveness.lag_allowance { - builder = - builder.with_expectation(ConsensusLiveness::default().with_lag_allowance(lag)); - } else { - builder = builder.expect_consensus_liveness(); - } - } - - Ok(builder) - } -} - -fn make_builder(topology: TopologySpec) -> Builder<()> { - ScenarioBuilder::topology_with(|t| { - let base = match topology.network { - NetworkKind::Star => t.network_star(), - }; - base.validators(topology.validators) - .executors(topology.executors) - }) -} - -fn is_truthy_env(key: &str) -> bool { - env::var(key) - .ok() - .is_some_and(|value| matches!(value.as_str(), "1" | "true" | "TRUE" | "yes" | "YES")) -} - -fn positive_usize(label: &str, value: usize) -> Result { - if value == 0 { - Err(StepError::InvalidArgument { - message: format!("{label} must be > 0"), - }) - } else { - Ok(value) - } -} - -fn positive_u64(label: &str, value: u64) -> Result { - if value == 0 { - Err(StepError::InvalidArgument { - message: format!("{label} must be > 0"), - }) - } else { - Ok(value) - } -} - -pub fn parse_deployer(value: &str) -> Result { - match value.trim().to_ascii_lowercase().as_str() { - "local" | "host" => Ok(DeployerKind::Local), - "compose" | "docker" => Ok(DeployerKind::Compose), - other => Err(StepError::UnsupportedDeployer { - value: other.to_owned(), - }), - } -} - -pub fn shared_host_bin_path(binary_name: &str) -> PathBuf { - let cucumber_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - cucumber_dir.join("../assets/stack/bin").join(binary_name) -} diff --git a/testing-framework/deployers/compose/Cargo.toml b/testing-framework/deployers/compose/Cargo.toml index f374f82..02f4432 100644 --- a/testing-framework/deployers/compose/Cargo.toml +++ b/testing-framework/deployers/compose/Cargo.toml @@ -13,22 +13,23 @@ version = "0.1.0" workspace = true [dependencies] -anyhow = "1" -async-trait = { workspace = true } -cfgsync = { workspace = true } -nomos-tracing = { workspace = true } -nomos-tracing-service = { workspace = true } -reqwest = { workspace = true, features = ["json"] } -serde = { workspace = true, features = ["derive"] } -tempfile = { workspace = true } -tera = "1.19" -testing-framework-core = { path = "../../core" } -testing-framework-env = { workspace = true } -thiserror = { workspace = true } -tokio = { workspace = true, features = ["macros", "net", "process", "rt-multi-thread", "sync", "time"] } -tracing = { workspace = true } -url = { version = "2" } -uuid = { version = "1", features = ["v4"] } +anyhow = "1" +async-trait = { workspace = true } +cfgsync_tf = { workspace = true } +nomos-tracing = { workspace = true } +nomos-tracing-service = { workspace = true } +reqwest = { workspace = true, features = ["json"] } +serde = { workspace = true, features = ["derive"] } +tempfile = { workspace = true } +tera = "1.19" +testing-framework-config = { workspace = true } +testing-framework-core = { path = "../../core" } +testing-framework-env = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true, features = ["macros", "net", "process", "rt-multi-thread", "sync", "time"] } +tracing = { workspace = true } +url = { version = "2" } +uuid = { version = "1", features = ["v4"] } [dev-dependencies] groth16 = { workspace = true } diff --git a/testing-framework/deployers/compose/src/deployer/mod.rs b/testing-framework/deployers/compose/src/deployer/mod.rs index 27dff56..03af600 100644 --- a/testing-framework/deployers/compose/src/deployer/mod.rs +++ b/testing-framework/deployers/compose/src/deployer/mod.rs @@ -87,7 +87,7 @@ pub(super) fn make_cleanup_guard( mod tests { use std::{collections::HashMap, net::Ipv4Addr}; - use cfgsync::{ + use cfgsync_tf::{ config::builder::create_node_configs, host::{Host, PortOverrides}, }; diff --git a/testing-framework/deployers/compose/src/descriptor/mod.rs b/testing-framework/deployers/compose/src/descriptor/mod.rs index 0fc1d40..b3d2360 100644 --- a/testing-framework/deployers/compose/src/descriptor/mod.rs +++ b/testing-framework/deployers/compose/src/descriptor/mod.rs @@ -5,7 +5,6 @@ use std::{ use serde::Serialize; use testing_framework_core::{ - constants::DEFAULT_CFGSYNC_PORT, kzg::KzgParamsSpec, topology::generation::{GeneratedNodeConfig, GeneratedTopology}, }; @@ -16,6 +15,7 @@ use crate::docker::platform::{host_gateway_entry, resolve_image}; mod node; pub use node::{EnvEntry, NodeDescriptor}; +use testing_framework_config::constants::DEFAULT_CFGSYNC_PORT; /// Top-level docker-compose descriptor built from a GeneratedTopology. #[derive(Clone, Debug, Serialize)] diff --git a/testing-framework/deployers/compose/src/docker/mod.rs b/testing-framework/deployers/compose/src/docker/mod.rs index 1896aa2..4dc6c45 100644 --- a/testing-framework/deployers/compose/src/docker/mod.rs +++ b/testing-framework/deployers/compose/src/docker/mod.rs @@ -5,6 +5,7 @@ pub mod workspace; use std::{env, process::Stdio, time::Duration}; +use testing_framework_config::constants::DEFAULT_ASSETS_STACK_DIR; use tokio::{process::Command, time::timeout}; use tracing::{debug, info, warn}; @@ -104,7 +105,9 @@ pub async fn build_local_image( ) -> Result<(), ComposeRunnerError> { let repo_root = repository_root().map_err(|source| ComposeRunnerError::ImageBuild { source })?; - let runtime_dockerfile = repo_root.join("testing-framework/assets/stack/Dockerfile.runtime"); + let runtime_dockerfile = repo_root + .join(DEFAULT_ASSETS_STACK_DIR) + .join("Dockerfile.runtime"); tracing::info!( image, diff --git a/testing-framework/deployers/compose/src/docker/workspace.rs b/testing-framework/deployers/compose/src/docker/workspace.rs index 752eaa0..4fe7eca 100644 --- a/testing-framework/deployers/compose/src/docker/workspace.rs +++ b/testing-framework/deployers/compose/src/docker/workspace.rs @@ -5,6 +5,10 @@ use std::{ use anyhow::{Context as _, Result}; use tempfile::TempDir; +use testing_framework_config::constants::{ + DEFAULT_ASSETS_STACK_DIR, DEFAULT_KZG_HOST_DIR, KZG_PARAMS_FILENAME, +}; +use testing_framework_env; use tracing::{debug, info}; /// Copy the repository stack assets into a scenario-specific temp dir. @@ -16,7 +20,8 @@ pub struct ComposeWorkspace { impl ComposeWorkspace { /// Clone the stack assets into a temporary directory. pub fn create() -> Result { - let repo_root = env::var("CARGO_WORKSPACE_DIR") + let repo_root = env::var("REPO_ROOT_OVERRIDE_DIR") + .or_else(|_| env::var("CARGO_WORKSPACE_DIR")) .map(PathBuf::from) .or_else(|_| { Path::new(env!("CARGO_MANIFEST_DIR")) @@ -49,8 +54,11 @@ impl ComposeWorkspace { copy_dir_recursive(&scripts_source, &temp.path().join("stack/scripts"))?; } - let kzg_source = repo_root.join("testing-framework/assets/stack/kzgrs_test_params"); - let target = temp.path().join("kzgrs_test_params"); + let kzg_source = repo_root.join( + testing_framework_env::nomos_kzg_dir_rel() + .unwrap_or_else(|| DEFAULT_KZG_HOST_DIR.to_string()), + ); + let target = temp.path().join(KZG_PARAMS_FILENAME); if kzg_source.exists() { if kzg_source.is_dir() { copy_dir_recursive(&kzg_source, &target)?; @@ -69,8 +77,14 @@ impl ComposeWorkspace { .unwrap_or(true) { anyhow::bail!( - "KZG params missing in stack assets (expected files in {})", - kzg_source.display() + "\nKZG params missing in stack assets (expected files in {})\ + \nrepo_root: {}\ + \ntarget: {}\ + \nnomos_kzg_dir_rel(): {:?}\n", + kzg_source.display(), + repo_root.display(), + target.display(), + testing_framework_env::nomos_kzg_dir_rel(), ); } @@ -98,7 +112,11 @@ impl ComposeWorkspace { } fn stack_assets_root(repo_root: &Path) -> PathBuf { - let new_layout = repo_root.join("testing-framework/assets/stack"); + let new_layout = if let Some(rel_stack_dir) = env::var("REL_ASSETS_STACK_DIR").ok() { + repo_root.join(rel_stack_dir) + } else { + repo_root.join(DEFAULT_ASSETS_STACK_DIR) + }; if new_layout.exists() { new_layout } else { @@ -107,7 +125,7 @@ fn stack_assets_root(repo_root: &Path) -> PathBuf { } fn stack_scripts_root(repo_root: &Path) -> PathBuf { - let new_layout = repo_root.join("testing-framework/assets/stack/scripts"); + let new_layout = repo_root.join(DEFAULT_ASSETS_STACK_DIR).join("scripts"); if new_layout.exists() { new_layout } else { diff --git a/testing-framework/deployers/compose/src/infrastructure/environment.rs b/testing-framework/deployers/compose/src/infrastructure/environment.rs index 1ea8e96..a85c7ee 100644 --- a/testing-framework/deployers/compose/src/infrastructure/environment.rs +++ b/testing-framework/deployers/compose/src/infrastructure/environment.rs @@ -6,6 +6,7 @@ use std::{ use anyhow::anyhow; use reqwest::Url; +use testing_framework_config::constants::KZG_PARAMS_FILENAME; use testing_framework_core::{ adjust_timeout, scenario::CleanupGuard, topology::generation::GeneratedTopology, }; @@ -151,7 +152,7 @@ pub fn prepare_workspace_state() -> Result { let workspace = ComposeWorkspace::create().map_err(WorkspaceError::new)?; let root = workspace.root_path().to_path_buf(); let cfgsync_path = workspace.stack_dir().join("cfgsync.yaml"); - let use_kzg = workspace.root_path().join("kzgrs_test_params").exists(); + let use_kzg = workspace.root_path().join(KZG_PARAMS_FILENAME).exists(); let state = WorkspaceState { workspace, diff --git a/testing-framework/deployers/k8s/Cargo.toml b/testing-framework/deployers/k8s/Cargo.toml index d0d92ff..7869e5c 100644 --- a/testing-framework/deployers/k8s/Cargo.toml +++ b/testing-framework/deployers/k8s/Cargo.toml @@ -13,20 +13,21 @@ version = "0.1.0" workspace = true [dependencies] -anyhow = "1" -async-trait = { workspace = true } -k8s-openapi = { version = "0.20", features = ["latest"] } -kube = { version = "0.87", default-features = false, features = ["client", "runtime", "rustls-tls"] } -nomos-tracing = { workspace = true } -nomos-tracing-service = { workspace = true } -reqwest = { workspace = true, features = ["json"] } -serde = { version = "1", features = ["derive"] } -serde_yaml = { workspace = true } -tempfile = { workspace = true } -testing-framework-core = { path = "../../core" } -testing-framework-env = { workspace = true } -thiserror = { workspace = true } -tokio = { workspace = true, features = ["macros", "net", "process", "rt-multi-thread", "sync", "time"] } -tracing = { workspace = true } -url = { version = "2" } -uuid = { version = "1", features = ["v4"] } +anyhow = "1" +async-trait = { workspace = true } +k8s-openapi = { version = "0.20", features = ["latest"] } +kube = { version = "0.87", default-features = false, features = ["client", "runtime", "rustls-tls"] } +nomos-tracing = { workspace = true } +nomos-tracing-service = { workspace = true } +reqwest = { workspace = true, features = ["json"] } +serde = { version = "1", features = ["derive"] } +serde_yaml = { workspace = true } +tempfile = { workspace = true } +testing-framework-config = { workspace = true } +testing-framework-core = { path = "../../core" } +testing-framework-env = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true, features = ["macros", "net", "process", "rt-multi-thread", "sync", "time"] } +tracing = { workspace = true } +url = { version = "2" } +uuid = { version = "1", features = ["v4"] } diff --git a/testing-framework/deployers/k8s/src/infrastructure/assets.rs b/testing-framework/deployers/k8s/src/infrastructure/assets.rs index f58afaa..909ec9e 100644 --- a/testing-framework/deployers/k8s/src/infrastructure/assets.rs +++ b/testing-framework/deployers/k8s/src/infrastructure/assets.rs @@ -10,9 +10,9 @@ use nomos_tracing_service::MetricsLayer; use reqwest::Url; use serde::Serialize; use tempfile::TempDir; +use testing_framework_config::constants::{DEFAULT_ASSETS_STACK_DIR, cfgsync_port}; pub use testing_framework_core::kzg::KzgMode; use testing_framework_core::{ - constants::cfgsync_port, kzg::KzgParamsSpec, scenario::cfgsync::{apply_topology_overrides, load_cfgsync_template, render_cfgsync_yaml}, topology::generation::GeneratedTopology, @@ -242,7 +242,7 @@ fn validate_scripts(root: &Path) -> Result { fn validate_kzg_params(root: &Path, spec: &KzgParamsSpec) -> Result { let Some(path) = spec.host_params_dir.clone() else { return Err(AssetsError::MissingKzg { - path: root.join(testing_framework_core::constants::DEFAULT_KZG_HOST_DIR), + path: root.join(testing_framework_config::constants::DEFAULT_KZG_HOST_DIR), }); }; if path.exists() { @@ -294,7 +294,7 @@ pub fn workspace_root() -> AnyResult { } fn stack_assets_root(root: &Path) -> PathBuf { - let new_layout = root.join("testing-framework/assets/stack"); + let new_layout = root.join(DEFAULT_ASSETS_STACK_DIR); if new_layout.exists() { new_layout } else { @@ -303,7 +303,7 @@ fn stack_assets_root(root: &Path) -> PathBuf { } fn stack_scripts_root(root: &Path) -> PathBuf { - let new_layout = root.join("testing-framework/assets/stack/scripts"); + let new_layout = root.join(DEFAULT_ASSETS_STACK_DIR).join("scripts"); if new_layout.exists() { new_layout } else { diff --git a/testing-framework/deployers/k8s/src/lifecycle/wait/mod.rs b/testing-framework/deployers/k8s/src/lifecycle/wait/mod.rs index 3b7edda..0c97ffa 100644 --- a/testing-framework/deployers/k8s/src/lifecycle/wait/mod.rs +++ b/testing-framework/deployers/k8s/src/lifecycle/wait/mod.rs @@ -1,13 +1,7 @@ use std::{env, sync::LazyLock, time::Duration}; use kube::Error as KubeError; -use testing_framework_core::{ - constants::{ - DEFAULT_HTTP_POLL_INTERVAL, DEFAULT_K8S_DEPLOYMENT_TIMEOUT, - DEFAULT_NODE_HTTP_PROBE_TIMEOUT, DEFAULT_NODE_HTTP_TIMEOUT, - }, - scenario::http_probe::NodeRole, -}; +use testing_framework_core::scenario::http_probe::NodeRole; use thiserror::Error; mod deployment; @@ -18,6 +12,10 @@ mod ports; pub use forwarding::PortForwardHandle; pub use orchestrator::wait_for_cluster_ready; +use testing_framework_config::constants::{ + DEFAULT_HTTP_POLL_INTERVAL, DEFAULT_K8S_DEPLOYMENT_TIMEOUT, DEFAULT_NODE_HTTP_PROBE_TIMEOUT, + DEFAULT_NODE_HTTP_TIMEOUT, +}; /// Container and host-side HTTP ports for a node in the Helm chart values. #[derive(Clone, Copy, Debug)] diff --git a/testing-framework/tools/cfgsync/Cargo.toml b/testing-framework/tools/cfgsync_tf/Cargo.toml similarity index 98% rename from testing-framework/tools/cfgsync/Cargo.toml rename to testing-framework/tools/cfgsync_tf/Cargo.toml index d672fd1..7dd5546 100644 --- a/testing-framework/tools/cfgsync/Cargo.toml +++ b/testing-framework/tools/cfgsync_tf/Cargo.toml @@ -4,7 +4,7 @@ description = { workspace = true } edition = { workspace = true } keywords = { workspace = true } license = { workspace = true } -name = "cfgsync" +name = "cfgsync_tf" readme = { workspace = true } repository = { workspace = true } version = { workspace = true } diff --git a/testing-framework/tools/cfgsync/src/bin/cfgsync-client.rs b/testing-framework/tools/cfgsync_tf/src/bin/cfgsync-client.rs similarity index 95% rename from testing-framework/tools/cfgsync/src/bin/cfgsync-client.rs rename to testing-framework/tools/cfgsync_tf/src/bin/cfgsync-client.rs index 1c247e4..3f43a84 100644 --- a/testing-framework/tools/cfgsync/src/bin/cfgsync-client.rs +++ b/testing-framework/tools/cfgsync_tf/src/bin/cfgsync-client.rs @@ -6,7 +6,7 @@ use std::{ str::FromStr, }; -use cfgsync::{ +use cfgsync_tf::{ client::{FetchedConfig, get_config}, server::ClientIp, }; @@ -15,9 +15,9 @@ use nomos_libp2p::PeerId; use nomos_node::Config as ValidatorConfig; use serde::{Serialize, de::DeserializeOwned}; use subnetworks_assignations::{MembershipCreator, MembershipHandler, SubnetworkId}; -use testing_framework_core::{ - constants::cfgsync_port as default_cfgsync_port, - nodes::common::config::injection::{inject_ibd_into_cryptarchia, normalize_ed25519_sigs}, +use testing_framework_config::constants::cfgsync_port as default_cfgsync_port; +use testing_framework_core::nodes::common::config::injection::{ + inject_ibd_into_cryptarchia, normalize_ed25519_sigs, }; fn parse_ip(ip_str: &str) -> Ipv4Addr { diff --git a/testing-framework/tools/cfgsync/src/bin/cfgsync-server.rs b/testing-framework/tools/cfgsync_tf/src/bin/cfgsync-server.rs similarity index 94% rename from testing-framework/tools/cfgsync/src/bin/cfgsync-server.rs rename to testing-framework/tools/cfgsync_tf/src/bin/cfgsync-server.rs index 8b2aa75..6d2cdae 100644 --- a/testing-framework/tools/cfgsync/src/bin/cfgsync-server.rs +++ b/testing-framework/tools/cfgsync_tf/src/bin/cfgsync-server.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use anyhow::Context as _; -use cfgsync::server::{CfgSyncConfig, cfgsync_app}; +use cfgsync_tf::server::{CfgSyncConfig, cfgsync_app}; use clap::Parser; use tokio::net::TcpListener; diff --git a/testing-framework/tools/cfgsync/src/client.rs b/testing-framework/tools/cfgsync_tf/src/client.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/client.rs rename to testing-framework/tools/cfgsync_tf/src/client.rs diff --git a/testing-framework/tools/cfgsync/src/config/builder.rs b/testing-framework/tools/cfgsync_tf/src/config/builder.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/config/builder.rs rename to testing-framework/tools/cfgsync_tf/src/config/builder.rs diff --git a/testing-framework/tools/cfgsync/src/config/kms.rs b/testing-framework/tools/cfgsync_tf/src/config/kms.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/config/kms.rs rename to testing-framework/tools/cfgsync_tf/src/config/kms.rs diff --git a/testing-framework/tools/cfgsync/src/config/providers.rs b/testing-framework/tools/cfgsync_tf/src/config/providers.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/config/providers.rs rename to testing-framework/tools/cfgsync_tf/src/config/providers.rs diff --git a/testing-framework/tools/cfgsync/src/config/tracing.rs b/testing-framework/tools/cfgsync_tf/src/config/tracing.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/config/tracing.rs rename to testing-framework/tools/cfgsync_tf/src/config/tracing.rs diff --git a/testing-framework/tools/cfgsync/src/config/validation.rs b/testing-framework/tools/cfgsync_tf/src/config/validation.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/config/validation.rs rename to testing-framework/tools/cfgsync_tf/src/config/validation.rs diff --git a/testing-framework/tools/cfgsync/src/host.rs b/testing-framework/tools/cfgsync_tf/src/host.rs similarity index 91% rename from testing-framework/tools/cfgsync/src/host.rs rename to testing-framework/tools/cfgsync_tf/src/host.rs index d382ba8..76c2f68 100644 --- a/testing-framework/tools/cfgsync/src/host.rs +++ b/testing-framework/tools/cfgsync_tf/src/host.rs @@ -1,9 +1,9 @@ use std::net::Ipv4Addr; -pub const DEFAULT_LIBP2P_NETWORK_PORT: u16 = 3000; -pub const DEFAULT_DA_NETWORK_PORT: u16 = 3300; -pub const DEFAULT_BLEND_PORT: u16 = 3400; -pub const DEFAULT_API_PORT: u16 = 18080; +use testing_framework_config::constants::{ + DEFAULT_API_PORT, DEFAULT_BLEND_NETWORK_PORT, DEFAULT_DA_NETWORK_PORT, + DEFAULT_LIBP2P_NETWORK_PORT, +}; #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub enum HostKind { @@ -40,7 +40,7 @@ impl Host { identifier, network_port: ports.network_port.unwrap_or(DEFAULT_LIBP2P_NETWORK_PORT), da_network_port: ports.da_network_port.unwrap_or(DEFAULT_DA_NETWORK_PORT), - blend_port: ports.blend_port.unwrap_or(DEFAULT_BLEND_PORT), + blend_port: ports.blend_port.unwrap_or(DEFAULT_BLEND_NETWORK_PORT), api_port: ports.api_port.unwrap_or(DEFAULT_API_PORT), testing_http_port: ports.testing_http_port.unwrap_or(DEFAULT_API_PORT + 1), } diff --git a/testing-framework/tools/cfgsync/src/lib.rs b/testing-framework/tools/cfgsync_tf/src/lib.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/lib.rs rename to testing-framework/tools/cfgsync_tf/src/lib.rs diff --git a/testing-framework/tools/cfgsync/src/network/address.rs b/testing-framework/tools/cfgsync_tf/src/network/address.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/network/address.rs rename to testing-framework/tools/cfgsync_tf/src/network/address.rs diff --git a/testing-framework/tools/cfgsync/src/network/mod.rs b/testing-framework/tools/cfgsync_tf/src/network/mod.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/network/mod.rs rename to testing-framework/tools/cfgsync_tf/src/network/mod.rs diff --git a/testing-framework/tools/cfgsync/src/network/peers.rs b/testing-framework/tools/cfgsync_tf/src/network/peers.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/network/peers.rs rename to testing-framework/tools/cfgsync_tf/src/network/peers.rs diff --git a/testing-framework/tools/cfgsync/src/repo.rs b/testing-framework/tools/cfgsync_tf/src/repo.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/repo.rs rename to testing-framework/tools/cfgsync_tf/src/repo.rs diff --git a/testing-framework/tools/cfgsync/src/server.rs b/testing-framework/tools/cfgsync_tf/src/server.rs similarity index 100% rename from testing-framework/tools/cfgsync/src/server.rs rename to testing-framework/tools/cfgsync_tf/src/server.rs