logos-blockchain-testing/docs/running-examples.html
2025-12-20 09:51:51 +01:00

499 lines
34 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Running Examples - Logos Blockchain Testing Framework Book</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="project-context-primer.html"><strong aria-hidden="true">1.</strong> Project Context Primer</a></li><li class="chapter-item expanded "><a href="what-you-will-learn.html"><strong aria-hidden="true">2.</strong> What You Will Learn</a></li><li class="chapter-item expanded "><a href="quickstart.html"><strong aria-hidden="true">3.</strong> Quickstart</a></li><li class="chapter-item expanded "><a href="part-i.html"><strong aria-hidden="true">4.</strong> Part I — Foundations</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">4.1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="architecture-overview.html"><strong aria-hidden="true">4.2.</strong> Architecture Overview</a></li><li class="chapter-item expanded "><a href="testing-philosophy.html"><strong aria-hidden="true">4.3.</strong> Testing Philosophy</a></li><li class="chapter-item expanded "><a href="scenario-lifecycle.html"><strong aria-hidden="true">4.4.</strong> Scenario Lifecycle</a></li><li class="chapter-item expanded "><a href="design-rationale.html"><strong aria-hidden="true">4.5.</strong> Design Rationale</a></li></ol></li><li class="chapter-item expanded "><a href="part-ii.html"><strong aria-hidden="true">5.</strong> Part II — User Guide</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="workspace-layout.html"><strong aria-hidden="true">5.1.</strong> Workspace Layout</a></li><li class="chapter-item expanded "><a href="annotated-tree.html"><strong aria-hidden="true">5.2.</strong> Annotated Tree</a></li><li class="chapter-item expanded "><a href="authoring-scenarios.html"><strong aria-hidden="true">5.3.</strong> Authoring Scenarios</a></li><li class="chapter-item expanded "><a href="workloads.html"><strong aria-hidden="true">5.4.</strong> Core Content: Workloads & Expectations</a></li><li class="chapter-item expanded "><a href="scenario-builder-ext-patterns.html"><strong aria-hidden="true">5.5.</strong> Core Content: ScenarioBuilderExt Patterns</a></li><li class="chapter-item expanded "><a href="best-practices.html"><strong aria-hidden="true">5.6.</strong> Best Practices</a></li><li class="chapter-item expanded "><a href="usage-patterns.html"><strong aria-hidden="true">5.7.</strong> Usage Patterns</a></li><li class="chapter-item expanded "><a href="examples.html"><strong aria-hidden="true">5.8.</strong> Examples</a></li><li class="chapter-item expanded "><a href="examples-advanced.html"><strong aria-hidden="true">5.9.</strong> Advanced & Artificial Examples</a></li><li class="chapter-item expanded "><a href="cucumber-bdd.html"><strong aria-hidden="true">5.10.</strong> Cucumber/BDD Interface</a></li><li class="chapter-item expanded "><a href="running-scenarios.html"><strong aria-hidden="true">5.11.</strong> Running Scenarios</a></li><li class="chapter-item expanded "><a href="runners.html"><strong aria-hidden="true">5.12.</strong> Runners</a></li><li class="chapter-item expanded "><a href="node-control.html"><strong aria-hidden="true">5.13.</strong> RunContext: BlockFeed & Node Control</a></li><li class="chapter-item expanded "><a href="chaos.html"><strong aria-hidden="true">5.14.</strong> Chaos Workloads</a></li><li class="chapter-item expanded "><a href="topology-chaos.html"><strong aria-hidden="true">5.15.</strong> Topology & Chaos Patterns</a></li></ol></li><li class="chapter-item expanded "><a href="part-iii.html"><strong aria-hidden="true">6.</strong> Part III — Developer Reference</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="scenario-model.html"><strong aria-hidden="true">6.1.</strong> Scenario Model (Developer Level)</a></li><li class="chapter-item expanded "><a href="api-levels.html"><strong aria-hidden="true">6.2.</strong> API Levels: Builder DSL vs. Direct</a></li><li class="chapter-item expanded "><a href="extending.html"><strong aria-hidden="true">6.3.</strong> Extending the Framework</a></li><li class="chapter-item expanded "><a href="custom-workload-example.html"><strong aria-hidden="true">6.4.</strong> Example: New Workload & Expectation (Rust)</a></li><li class="chapter-item expanded "><a href="internal-crate-reference.html"><strong aria-hidden="true">6.5.</strong> Internal Crate Reference</a></li></ol></li><li class="chapter-item expanded "><a href="part-iv.html"><strong aria-hidden="true">7.</strong> Part IV — Operations & Deployment</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="operations-overview.html"><strong aria-hidden="true">7.1.</strong> Overview</a></li><li class="chapter-item expanded "><a href="prerequisites.html"><strong aria-hidden="true">7.2.</strong> Prerequisites & Setup</a></li><li class="chapter-item expanded "><a href="running-examples.html" class="active"><strong aria-hidden="true">7.3.</strong> Running Examples</a></li><li class="chapter-item expanded "><a href="ci-integration.html"><strong aria-hidden="true">7.4.</strong> CI Integration</a></li><li class="chapter-item expanded "><a href="environment-variables.html"><strong aria-hidden="true">7.5.</strong> Environment Variables</a></li><li class="chapter-item expanded "><a href="logging-observability.html"><strong aria-hidden="true">7.6.</strong> Logging & Observability</a></li></ol></li><li class="chapter-item expanded "><a href="part-v.html"><strong aria-hidden="true">8.</strong> Part V — Appendix</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="dsl-cheat-sheet.html"><strong aria-hidden="true">8.1.</strong> Builder API Quick Reference</a></li><li class="chapter-item expanded "><a href="troubleshooting.html"><strong aria-hidden="true">8.2.</strong> Troubleshooting Scenarios</a></li><li class="chapter-item expanded "><a href="faq.html"><strong aria-hidden="true">8.3.</strong> FAQ</a></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.4.</strong> Glossary</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Logos Blockchain Testing Framework Book</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="running-examples"><a class="header" href="#running-examples">Running Examples</a></h1>
<p>The framework provides three runner modes: <strong>host</strong> (local processes), <strong>compose</strong> (Docker Compose), and <strong>k8s</strong> (Kubernetes).</p>
<h2 id="quick-start-recommended"><a class="header" href="#quick-start-recommended">Quick Start (Recommended)</a></h2>
<p>Use <code>scripts/run/run-examples.sh</code> for all modes—it handles all setup automatically:</p>
<pre><code class="language-bash"># Host mode (local processes)
scripts/run/run-examples.sh -t 60 -v 3 -e 1 host
# Compose mode (Docker Compose)
scripts/run/run-examples.sh -t 60 -v 3 -e 1 compose
# K8s mode (Kubernetes)
scripts/run/run-examples.sh -t 60 -v 3 -e 1 k8s
</code></pre>
<p><strong>Parameters:</strong></p>
<ul>
<li><code>-t 60</code> — Run duration in seconds</li>
<li><code>-v 3</code> — Number of validators</li>
<li><code>-e 1</code> — Number of executors</li>
<li><code>host|compose|k8s</code> — Deployment mode</li>
</ul>
<p>This script handles:</p>
<ul>
<li>Circuit asset setup</li>
<li>Binary building/bundling</li>
<li>Image building (compose/k8s)</li>
<li>Image loading into cluster (k8s)</li>
<li>Execution with proper environment</li>
</ul>
<p><strong>Note:</strong> For <code>k8s</code> runs against non-local clusters (e.g. EKS), the cluster pulls images from a registry. In that case, build + push your image separately (see <code>scripts/build/build_test_image.sh</code>) and set <code>NOMOS_TESTNET_IMAGE</code> to the pushed reference.</p>
<h2 id="quick-smoke-matrix"><a class="header" href="#quick-smoke-matrix">Quick Smoke Matrix</a></h2>
<p>For a small "does everything still run?" matrix across all runners:</p>
<pre><code class="language-bash">scripts/run/run-test-matrix.sh -t 120 -v 1 -e 1
</code></pre>
<p>This runs host, compose, and k8s modes with various image-build configurations. Useful after making runner/image/script changes. Forwards <code>--metrics-*</code> options through to <code>scripts/run/run-examples.sh</code>.</p>
<p><strong>Common options:</strong></p>
<ul>
<li><code>--modes host,compose,k8s</code> — Restrict which modes run</li>
<li><code>--no-clean</code> — Skip <code>scripts/ops/clean.sh</code> step</li>
<li><code>--no-bundles</code> — Skip <code>scripts/build/build-bundle.sh</code> (reuses existing <code>.tmp</code> tarballs)</li>
<li><code>--no-image-build</code> — Skip the “rebuild image” variants in the matrix (compose/k8s)</li>
<li><code>--allow-nonzero-progress</code> — Soft-pass expectation failures if logs show non-zero progress (local iteration only)</li>
<li><code>--force-k8s-image-build</code> — Allow the k8s image-build variant even on non-docker-desktop clusters</li>
</ul>
<p><strong>Environment overrides:</strong></p>
<ul>
<li><code>VERSION=v0.3.1</code> — Circuit version</li>
<li><code>NOMOS_NODE_REV=&lt;commit&gt;</code> — nomos-node git revision</li>
<li><code>NOMOS_BINARIES_TAR=path/to/bundle.tar.gz</code> — Use prebuilt bundle</li>
<li><code>NOMOS_SKIP_IMAGE_BUILD=1</code> — Skip image rebuild inside <code>run-examples.sh</code> (compose/k8s)</li>
<li><code>NOMOS_BUNDLE_DOCKER_PLATFORM=linux/arm64|linux/amd64</code> — Docker platform for bundle builds (macOS/Windows)</li>
<li><code>COMPOSE_CIRCUITS_PLATFORM=linux-aarch64|linux-x86_64</code> — Circuits platform for image builds</li>
<li><code>SLOW_TEST_ENV=true</code> — Doubles built-in readiness timeouts (useful in CI / constrained laptops)</li>
<li><code>TESTNET_PRINT_ENDPOINTS=1</code> — Print <code>TESTNET_ENDPOINTS</code> / <code>TESTNET_PPROF</code> lines during deploy</li>
</ul>
<h2 id="dev-workflow-updating-nomos-node-revision"><a class="header" href="#dev-workflow-updating-nomos-node-revision">Dev Workflow: Updating nomos-node Revision</a></h2>
<p>The repo pins a <code>nomos-node</code> revision in <code>versions.env</code> for reproducible builds. To update it or point to a local checkout:</p>
<pre><code class="language-bash"># Pin to a new git revision (updates versions.env + Cargo.toml git revs)
scripts/ops/update-nomos-rev.sh --rev &lt;git_sha&gt;
# Use a local nomos-node checkout instead (for development)
scripts/ops/update-nomos-rev.sh --path /path/to/nomos-node
# If Cargo.toml was marked skip-worktree, clear it
scripts/ops/update-nomos-rev.sh --unskip-worktree
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li>Don't commit absolute <code>NOMOS_NODE_PATH</code> values; prefer <code>--rev</code> for shared history/CI</li>
<li>After changing rev/path, expect <code>Cargo.lock</code> to update on the next <code>cargo build</code>/<code>cargo test</code></li>
</ul>
<h2 id="cleanup-helper"><a class="header" href="#cleanup-helper">Cleanup Helper</a></h2>
<p>If you hit Docker build failures, I/O errors, or disk space issues:</p>
<pre><code class="language-bash">scripts/ops/clean.sh
</code></pre>
<p>For extra Docker cache cleanup:</p>
<pre><code class="language-bash">scripts/ops/clean.sh --docker
</code></pre>
<hr />
<h2 id="host-runner-direct-cargo-run"><a class="header" href="#host-runner-direct-cargo-run">Host Runner (Direct Cargo Run)</a></h2>
<p>For manual control, run the <code>local_runner</code> binary directly:</p>
<pre><code class="language-bash">POL_PROOF_DEV_MODE=true \
NOMOS_NODE_BIN=/path/to/nomos-node \
NOMOS_EXECUTOR_BIN=/path/to/nomos-executor \
cargo run -p runner-examples --bin local_runner
</code></pre>
<h3 id="host-runner-environment-variables"><a class="header" href="#host-runner-environment-variables">Host Runner Environment Variables</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Variable</th><th>Default</th><th>Effect</th></tr></thead><tbody>
<tr><td><code>NOMOS_DEMO_VALIDATORS</code></td><td>1</td><td>Number of validators (legacy: <code>LOCAL_DEMO_VALIDATORS</code>)</td></tr>
<tr><td><code>NOMOS_DEMO_EXECUTORS</code></td><td>1</td><td>Number of executors (legacy: <code>LOCAL_DEMO_EXECUTORS</code>)</td></tr>
<tr><td><code>NOMOS_DEMO_RUN_SECS</code></td><td>60</td><td>Run duration in seconds (legacy: <code>LOCAL_DEMO_RUN_SECS</code>)</td></tr>
<tr><td><code>NOMOS_NODE_BIN</code></td><td></td><td>Path to nomos-node binary (required)</td></tr>
<tr><td><code>NOMOS_EXECUTOR_BIN</code></td><td></td><td>Path to nomos-executor binary (required)</td></tr>
<tr><td><code>NOMOS_LOG_DIR</code></td><td>None</td><td>Directory for per-node log files</td></tr>
<tr><td><code>NOMOS_TESTS_KEEP_LOGS</code></td><td>0</td><td>Keep per-run temporary directories (useful for debugging/CI)</td></tr>
<tr><td><code>NOMOS_TESTS_TRACING</code></td><td>false</td><td>Enable debug tracing preset</td></tr>
<tr><td><code>NOMOS_LOG_LEVEL</code></td><td>info</td><td>Global log level: error, warn, info, debug, trace</td></tr>
<tr><td><code>NOMOS_LOG_FILTER</code></td><td>None</td><td>Fine-grained module filtering (e.g., <code>cryptarchia=trace,nomos_da_sampling=debug</code>)</td></tr>
<tr><td><code>POL_PROOF_DEV_MODE</code></td><td></td><td><strong>REQUIRED</strong>: Set to <code>true</code> for all runners</td></tr>
</tbody></table>
</div>
<p><strong>Note:</strong> Requires circuit assets and host binaries. Use <code>scripts/run/run-examples.sh host</code> to handle setup automatically.</p>
<hr />
<h2 id="compose-runner-direct-cargo-run"><a class="header" href="#compose-runner-direct-cargo-run">Compose Runner (Direct Cargo Run)</a></h2>
<p>For manual control, run the <code>compose_runner</code> binary directly. Compose requires a Docker image with embedded assets.</p>
<h3 id="option-1-prebuilt-bundle-recommended"><a class="header" href="#option-1-prebuilt-bundle-recommended">Option 1: Prebuilt Bundle (Recommended)</a></h3>
<pre><code class="language-bash"># 1. Build a Linux bundle (includes binaries + circuits)
scripts/build/build-bundle.sh --platform linux
# Creates .tmp/nomos-binaries-linux-v0.3.1.tar.gz
# 2. Build image (embeds bundle assets)
export NOMOS_BINARIES_TAR=.tmp/nomos-binaries-linux-v0.3.1.tar.gz
scripts/build/build_test_image.sh
# 3. Run
NOMOS_TESTNET_IMAGE=logos-blockchain-testing:local \
POL_PROOF_DEV_MODE=true \
cargo run -p runner-examples --bin compose_runner
</code></pre>
<h3 id="option-2-manual-circuitimage-setup"><a class="header" href="#option-2-manual-circuitimage-setup">Option 2: Manual Circuit/Image Setup</a></h3>
<pre><code class="language-bash"># Fetch and copy circuits
scripts/setup/setup-nomos-circuits.sh v0.3.1 /tmp/nomos-circuits
cp -r /tmp/nomos-circuits/* testing-framework/assets/stack/kzgrs_test_params/
# Build image
scripts/build/build_test_image.sh
# Run
NOMOS_TESTNET_IMAGE=logos-blockchain-testing:local \
POL_PROOF_DEV_MODE=true \
cargo run -p runner-examples --bin compose_runner
</code></pre>
<h3 id="platform-note-macos--apple-silicon"><a class="header" href="#platform-note-macos--apple-silicon">Platform Note (macOS / Apple Silicon)</a></h3>
<ul>
<li>Docker Desktop runs a <code>linux/arm64</code> engine by default</li>
<li>For native performance: <code>NOMOS_BUNDLE_DOCKER_PLATFORM=linux/arm64</code> (recommended for local testing)</li>
<li>For amd64 targets: <code>NOMOS_BUNDLE_DOCKER_PLATFORM=linux/amd64</code> (slower via emulation)</li>
</ul>
<h3 id="compose-runner-environment-variables"><a class="header" href="#compose-runner-environment-variables">Compose Runner Environment Variables</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Variable</th><th>Default</th><th>Effect</th></tr></thead><tbody>
<tr><td><code>NOMOS_TESTNET_IMAGE</code></td><td></td><td>Image tag (required, must match built image)</td></tr>
<tr><td><code>POL_PROOF_DEV_MODE</code></td><td></td><td><strong>REQUIRED</strong>: Set to <code>true</code> for all runners</td></tr>
<tr><td><code>NOMOS_DEMO_VALIDATORS</code></td><td>1</td><td>Number of validators</td></tr>
<tr><td><code>NOMOS_DEMO_EXECUTORS</code></td><td>1</td><td>Number of executors</td></tr>
<tr><td><code>NOMOS_DEMO_RUN_SECS</code></td><td>60</td><td>Run duration in seconds</td></tr>
<tr><td><code>COMPOSE_NODE_PAIRS</code></td><td></td><td>Alternative topology format: "validators×executors" (e.g., <code>3x2</code>)</td></tr>
<tr><td><code>NOMOS_METRICS_QUERY_URL</code></td><td>None</td><td>Prometheus-compatible base URL for runner to query</td></tr>
<tr><td><code>NOMOS_METRICS_OTLP_INGEST_URL</code></td><td>None</td><td>Full OTLP HTTP ingest URL for node metrics export</td></tr>
<tr><td><code>NOMOS_GRAFANA_URL</code></td><td>None</td><td>Grafana base URL for printing/logging</td></tr>
<tr><td><code>COMPOSE_RUNNER_HOST</code></td><td>127.0.0.1</td><td>Host address for port mappings</td></tr>
<tr><td><code>COMPOSE_RUNNER_PRESERVE</code></td><td>0</td><td>Keep containers running after test</td></tr>
<tr><td><code>NOMOS_LOG_LEVEL</code></td><td>info</td><td>Node log level (stdout/stderr)</td></tr>
<tr><td><code>NOMOS_LOG_FILTER</code></td><td>None</td><td>Fine-grained module filtering</td></tr>
</tbody></table>
</div>
<p><strong>Config file option:</strong> <code>testing-framework/assets/stack/cfgsync.yaml</code> (<code>tracing_settings.logger</code>) — Switch node logs between stdout/stderr and file output</p>
<h3 id="compose-specific-features"><a class="header" href="#compose-specific-features">Compose-Specific Features</a></h3>
<ul>
<li><strong>Node control support</strong>: Only runner that supports chaos testing (<code>.enable_node_control()</code> + chaos workloads)</li>
<li><strong>External observability</strong>: Set <code>NOMOS_METRICS_*</code> / <code>NOMOS_GRAFANA_URL</code> to enable telemetry links and querying
<ul>
<li>Quickstart: <code>scripts/setup/setup-observability.sh compose up</code> then <code>scripts/setup/setup-observability.sh compose env</code></li>
</ul>
</li>
</ul>
<p><strong>Important:</strong></p>
<ul>
<li>Containers expect KZG parameters at <code>/kzgrs_test_params/kzgrs_test_params</code> (note the repeated filename)</li>
<li>Use <code>scripts/run/run-examples.sh compose</code> to handle all setup automatically</li>
</ul>
<hr />
<h2 id="k8s-runner-direct-cargo-run"><a class="header" href="#k8s-runner-direct-cargo-run">K8s Runner (Direct Cargo Run)</a></h2>
<p>For manual control, run the <code>k8s_runner</code> binary directly. K8s requires the same image setup as Compose.</p>
<h3 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h3>
<ol>
<li><strong>Kubernetes cluster</strong> with <code>kubectl</code> configured</li>
<li><strong>Test image built</strong> (same as Compose, preferably with prebuilt bundle)</li>
<li><strong>Image available in cluster</strong> (loaded or pushed to registry)</li>
</ol>
<h3 id="build-and-load-image"><a class="header" href="#build-and-load-image">Build and Load Image</a></h3>
<pre><code class="language-bash"># 1. Build image with bundle (recommended)
scripts/build/build-bundle.sh --platform linux
export NOMOS_BINARIES_TAR=.tmp/nomos-binaries-linux-v0.3.1.tar.gz
scripts/build/build_test_image.sh
# 2. Load into cluster (choose one)
export NOMOS_TESTNET_IMAGE=logos-blockchain-testing:local
# For kind:
kind load docker-image logos-blockchain-testing:local
# For minikube:
minikube image load logos-blockchain-testing:local
# For remote cluster (push to registry):
docker tag logos-blockchain-testing:local your-registry/logos-blockchain-testing:latest
docker push your-registry/logos-blockchain-testing:latest
export NOMOS_TESTNET_IMAGE=your-registry/logos-blockchain-testing:latest
</code></pre>
<h3 id="run-the-example"><a class="header" href="#run-the-example">Run the Example</a></h3>
<pre><code class="language-bash">export NOMOS_TESTNET_IMAGE=logos-blockchain-testing:local
export POL_PROOF_DEV_MODE=true
cargo run -p runner-examples --bin k8s_runner
</code></pre>
<h3 id="k8s-runner-environment-variables"><a class="header" href="#k8s-runner-environment-variables">K8s Runner Environment Variables</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Variable</th><th>Default</th><th>Effect</th></tr></thead><tbody>
<tr><td><code>NOMOS_TESTNET_IMAGE</code></td><td></td><td>Image tag (required)</td></tr>
<tr><td><code>POL_PROOF_DEV_MODE</code></td><td></td><td><strong>REQUIRED</strong>: Set to <code>true</code> for all runners</td></tr>
<tr><td><code>NOMOS_DEMO_VALIDATORS</code></td><td>1</td><td>Number of validators</td></tr>
<tr><td><code>NOMOS_DEMO_EXECUTORS</code></td><td>1</td><td>Number of executors</td></tr>
<tr><td><code>NOMOS_DEMO_RUN_SECS</code></td><td>60</td><td>Run duration in seconds</td></tr>
<tr><td><code>NOMOS_METRICS_QUERY_URL</code></td><td>None</td><td>Prometheus-compatible base URL for runner to query (PromQL)</td></tr>
<tr><td><code>NOMOS_METRICS_OTLP_INGEST_URL</code></td><td>None</td><td>Full OTLP HTTP ingest URL for node metrics export</td></tr>
<tr><td><code>NOMOS_GRAFANA_URL</code></td><td>None</td><td>Grafana base URL for printing/logging</td></tr>
<tr><td><code>K8S_RUNNER_NAMESPACE</code></td><td>Random</td><td>Kubernetes namespace (pin for debugging)</td></tr>
<tr><td><code>K8S_RUNNER_RELEASE</code></td><td>Random</td><td>Helm release name (pin for debugging)</td></tr>
<tr><td><code>K8S_RUNNER_NODE_HOST</code></td><td></td><td>NodePort host resolution for non-local clusters</td></tr>
<tr><td><code>K8S_RUNNER_DEBUG</code></td><td>0</td><td>Log Helm stdout/stderr for install commands</td></tr>
<tr><td><code>K8S_RUNNER_PRESERVE</code></td><td>0</td><td>Keep namespace/release after run (for debugging)</td></tr>
</tbody></table>
</div>
<h3 id="k8s--observability-optional"><a class="header" href="#k8s--observability-optional">K8s + Observability (Optional)</a></h3>
<pre><code class="language-bash">export NOMOS_METRICS_QUERY_URL=http://your-prometheus:9090
# Prometheus OTLP receiver example:
export NOMOS_METRICS_OTLP_INGEST_URL=http://your-prometheus:9090/api/v1/otlp/v1/metrics
# Optional: print Grafana link in TESTNET_ENDPOINTS
export NOMOS_GRAFANA_URL=http://your-grafana:3000
cargo run -p runner-examples --bin k8s_runner
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li><code>NOMOS_METRICS_QUERY_URL</code> must be reachable from the runner process (often via <code>kubectl port-forward</code>)</li>
<li><code>NOMOS_METRICS_OTLP_INGEST_URL</code> must be reachable from nodes (pods/containers) and is backend-specific
<ul>
<li>Quickstart installer: <code>scripts/setup/setup-observability.sh k8s install</code> then <code>scripts/setup/setup-observability.sh k8s env</code></li>
<li>Optional dashboards: <code>scripts/setup/setup-observability.sh k8s dashboards</code></li>
</ul>
</li>
</ul>
<h3 id="via-scriptsrunrun-examplessh-recommended"><a class="header" href="#via-scriptsrunrun-examplessh-recommended">Via <code>scripts/run/run-examples.sh</code> (Recommended)</a></h3>
<pre><code class="language-bash">scripts/run/run-examples.sh -t 60 -v 3 -e 1 k8s \
--metrics-query-url http://your-prometheus:9090 \
--metrics-otlp-ingest-url http://your-prometheus:9090/api/v1/otlp/v1/metrics
</code></pre>
<h3 id="in-code-optional"><a class="header" href="#in-code-optional">In Code (Optional)</a></h3>
<pre><code class="language-rust ignore">use testing_framework_core::scenario::ScenarioBuilder;
use testing_framework_workflows::ObservabilityBuilderExt as _;
let plan = ScenarioBuilder::with_node_counts(1, 1)
.with_metrics_query_url_str("http://your-prometheus:9090")
.with_metrics_otlp_ingest_url_str("http://your-prometheus:9090/api/v1/otlp/v1/metrics")
.build();</code></pre>
<h3 id="important-k8s-notes"><a class="header" href="#important-k8s-notes">Important K8s Notes</a></h3>
<ul>
<li>K8s runner mounts <code>testing-framework/assets/stack/kzgrs_test_params</code> as a hostPath volume</li>
<li>File path inside pods: <code>/kzgrs_test_params/kzgrs_test_params</code></li>
<li><strong>No node control support yet</strong>: Chaos workloads (<code>.enable_node_control()</code>) will fail</li>
<li>Optimized for local clusters (Docker Desktop K8s / minikube / kind)
<ul>
<li>Remote clusters require additional setup (registry push, PV/CSI for assets, etc.)</li>
</ul>
</li>
<li>Use <code>scripts/run/run-examples.sh k8s</code> to handle all setup automatically</li>
</ul>
<h2 id="next-steps"><a class="header" href="#next-steps">Next Steps</a></h2>
<ul>
<li><a href="ci-integration.html">CI Integration</a> — Automate tests in continuous integration</li>
<li><a href="environment-variables.html">Environment Variables</a> — Full variable reference</li>
<li><a href="logging-observability.html">Logging &amp; Observability</a> — Log collection and metrics</li>
<li><a href="troubleshooting.html">Troubleshooting</a> — Common issues and fixes</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="prerequisites.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ci-integration.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="prerequisites.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="ci-integration.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
<script src="theme/mermaid-init.js"></script>
</div>
</body>
</html>