Skip to content

Implement mesh-bench#56

Open
xzyaoi wants to merge 22 commits intomainfrom
net-profiler
Open

Implement mesh-bench#56
xzyaoi wants to merge 22 commits intomainfrom
net-profiler

Conversation

@xzyaoi
Copy link
Copy Markdown
Collaborator

@xzyaoi xzyaoi commented May 3, 2026

This pull request introduces a new "network-profiler" tool in the contrib/network-profiler directory. The tool enables profiling of pairwise network conditions (latency and bandwidth) across machines managed by the remote-cluster-controller, with support for running isolated libp2p mesh benchmarks. The implementation includes configuration, orchestration, measurement collection, result rendering, and a command-line interface.

The most important changes are:

Core Functionality and CLI:

  • Added a comprehensive CLI (network_profiler/cli.py) supporting commands to plan, collect, render heatmaps, and run isolated mesh benchmarks, allowing users to easily profile and visualize network conditions across clusters.
  • Implemented the main entrypoint (network_profiler/__main__.py) and package versioning (network_profiler/__init__.py). [1] [2]

Benchmark Orchestration:

  • Developed a full benchmarking orchestration module (network_profiler/bench.py) that automates multi-phase remote setup, configuration, execution, health checking, convergence, measurement collection, and teardown for libp2p mesh network benchmarks.
  • Added configuration rendering logic (network_profiler/bench_config.py) to generate per-host configuration files for the benchmarking process, supporting flexible bootstrapping and port assignment.

Project Setup and Documentation:

  • Added a detailed README.md with instructions, usage examples, and requirements for using the network profiler tool.
  • Added a Makefile for running tests and smoke benchmarks, and a .gitignore for common Python and results files. [1] [2]

xzyaoi and others added 22 commits May 2, 2026 17:33
Spec for an OpenTela-native pairwise network profiler that brings up an
isolated mesh on remote machines, measures libp2p_ping / HTTP-over-libp2p
latency / throughput across every pair, and writes JSONL.

Motivated by the relay-circuit NO_RESERVATION debugging effort: raw IP
ping/iperf3 numbers don't characterise what production traffic actually
experiences (TLS, multiplexing, relay hops). Adds /v1/probe/echo,
/v1/probe/run, libp2p ping registration, and otela probe / peer-id CLI
commands as always-on diagnostic surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Allows multiple otela processes to coexist on one host with isolated
config and key storage. Foundation for the mesh-bench runner.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When --config-dir was set and no cfg.yaml existed yet, initConfig
seeded the file at a relative path instead of inside the config dir,
breaking otela init --config-dir on fresh dirs (the mesh-bench's
happy path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lets the mesh-bench runner read the PeerID before any otela start
call. Idempotent: existing keys are left alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GenerateAndWriteKey now returns the generated key directly so newHost
doesn't have to immediately reload from disk. The init_test now
restores viper state via t.Cleanup so config_dir doesn't leak into
other tests in the same package binary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prints the local libp2p PeerID by reading the key from disk. Used by
the mesh-bench runner to discover PeerIDs before bringing up the mesh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Always-on diagnostic surface: every otela node now responds to libp2p
ping. Used by the mesh-bench libp2p_ping probe kind.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Streams N zero bytes back, capped at 1 GiB. Throughput counterpart for
the mesh-bench probe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Calling c.Writer.Flush() per chunk ensures the libp2p-http transport
sees bytes incrementally — without it, throughput measurements would
show inflated tail latency. Also adds a debug log on write errors and
asserts the echo body is actually zero bytes for small n.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three kinds: latency (HTTP-over-libp2p RTT to /v1/health), throughput
(byte-stream from /v1/probe/echo), libp2p_ping (raw /ipfs/ping/1.0.0
RTT). Reuses the global libp2p HTTP transport from the proxy handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ping.Ping(ctx, h, pid) avoids re-registering the global stream handler
on every probe request (NewPingService overwrites the host's existing
handler as a side effect).

Throughput's aggregate mbps is now total_bytes * 8 / total_elapsed
across all iterations, rather than the mean of per-iteration mbps.
The per-iteration array still records each iteration's instant mbps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Thin client over /v1/probe/run on the local node. Used by the
mesh-bench runner to dispatch per-pair probes via rcc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure functions to build per-host opentela cfg.yaml for an isolated
bench mesh: ports, bootstrap multiaddrs, feature flags off.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per-host otela init and peer-id discovery for the mesh-bench runner.
Pure orchestration over the existing RemoteRunner.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renders per-host cfg.yaml with bootstrap multiaddrs and pushes via
base64-piped stdin. RemoteRunner gains stdin support.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Background-launch otela on each host, poll /v1/health for readiness,
then poll /v1/dnt/table for full mesh convergence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pairwise (src, dst, kind) sweep that calls otela probe via rcc and
writes one JSONL record per measurement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pkill matched on the unique bench cfg path, then rm -rf the bench dir.
Best-effort: pkill returning 1 (no match) is not a failure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Top-level orchestrator with signal-safe teardown, phase timing, and
run.json summary alongside measurements.jsonl.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Local two-node validation runs the full bench pipeline against
loopback. Per-machine http_port/libp2p_port overrides allow multiple
nodes on a single host. phase_start now passes --config-dir so otela
loads the libp2p key from the bench dir (matching what peer-id
discovered) rather than the default ~/.config/opentela location.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 3, 2026 16:35
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

Test Coverage Report 📊

Click to view detailed coverage
opentela/entry/cmd/init.go:21:					ensureLibp2pKey			85.7%
opentela/entry/cmd/init.go:131:					writeDefaultConfig		0.0%
opentela/entry/cmd/probe.go:77:					init				100.0%
opentela/entry/cmd/root.go:35:					init				96.6%
opentela/entry/cmd/root.go:77:					configFilePath			85.7%
opentela/entry/cmd/root.go:92:					initConfig			87.1%
opentela/entry/cmd/root.go:239:					Execute				0.0%
opentela/entry/cmd/start.go:40:					init				100.0%
opentela/entry/cmd/update.go:13:				doUpdate			0.0%
opentela/entry/cmd/wallet.go:388:				init				100.0%
opentela/entry/main.go:18:					main				0.0%
opentela/internal/attestation/attestation.go:43:		loadPubKey			53.8%
opentela/internal/attestation/attestation.go:65:		attestationMessage		100.0%
opentela/internal/attestation/attestation.go:72:		Verify				75.0%
opentela/internal/attestation/attestation.go:96:		Sign				100.0%
opentela/internal/attestation/cmd/buildsign/main.go:22:		main				0.0%
opentela/internal/attestation/cmd/buildsign/main.go:39:		keygen				0.0%
opentela/internal/attestation/cmd/buildsign/main.go:51:		sign				0.0%
opentela/internal/common/constants.go:10:			GetHomePath			63.6%
opentela/internal/common/constants.go:27:			GetDBPath			100.0%
opentela/internal/common/filesystem.go:7:			RemoveDir			100.0%
opentela/internal/common/logger.go:11:				init				100.0%
opentela/internal/common/logger.go:15:				InitLogger			50.0%
opentela/internal/common/logger.go:55:				ReportError			50.0%
opentela/internal/common/process/manager.go:13:			NewProcessManager		100.0%
opentela/internal/common/process/manager.go:20:			StartProcess			0.0%
opentela/internal/common/process/manager.go:27:			StopAllProcesses		0.0%
opentela/internal/common/process/manager.go:33:			StartCriticalProcess		57.1%
opentela/internal/common/process/manager.go:44:			HealthCheck			50.0%
opentela/internal/common/process/process.go:36:			NewProcess			100.0%
opentela/internal/common/process/process.go:63:			Start				94.4%
opentela/internal/common/process/process.go:93:			SetTimeout			66.7%
opentela/internal/common/process/process.go:101:		Wait				100.0%
opentela/internal/common/process/process.go:105:		awaitOutput			100.0%
opentela/internal/common/process/process.go:111:		Kill				100.0%
opentela/internal/common/process/process.go:120:		OpenInputStream			71.4%
opentela/internal/common/process/process.go:133:		StreamOutput			77.8%
opentela/internal/common/process/process.go:151:		finishTimeOutOrDie		87.5%
opentela/internal/common/process/process.go:169:		cleanup				100.0%
opentela/internal/common/process/process.go:181:		isRunning			0.0%
opentela/internal/common/requests.go:12:			RemoteGET			52.6%
opentela/internal/common/serialization.go:5:			DictionaryToBytes		100.0%
opentela/internal/common/utils.go:3:				DeduplicateStrings		100.0%
opentela/internal/ingest/server.go:40:				Run				0.0%
opentela/internal/ingest/server.go:70:				collectStats			0.0%
opentela/internal/metrics/collector.go:20:			NewAggregatedCollector		100.0%
opentela/internal/metrics/collector.go:38:			Describe			0.0%
opentela/internal/metrics/collector.go:42:			Collect				88.9%
opentela/internal/metrics/collector.go:58:			SetNetworkStats			100.0%
opentela/internal/metrics/collector.go:63:			SetScraperTargets		100.0%
opentela/internal/metrics/collector.go:67:			metricFromDTO			91.7%
opentela/internal/metrics/peer_provider.go:15:			GetScrapablePeers		0.0%
opentela/internal/metrics/peer_provider.go:42:			extractServices			100.0%
opentela/internal/metrics/peer_provider.go:57:			buildPeerLabels			100.0%
opentela/internal/metrics/relabeler.go:12:			Relabel				100.0%
opentela/internal/metrics/relabeler.go:53:			sanitizeMetricName		75.0%
opentela/internal/metrics/scraper.go:54:			NewMetricsScraper		100.0%
opentela/internal/metrics/scraper.go:83:			Start				0.0%
opentela/internal/metrics/scraper.go:99:			Stop				0.0%
opentela/internal/metrics/scraper.go:103:			GetCachedMetrics		100.0%
opentela/internal/metrics/scraper.go:114:			GetSelfMetrics			0.0%
opentela/internal/metrics/scraper.go:118:			scrapeAll			100.0%
opentela/internal/metrics/scraper.go:145:			scrapePeer			72.7%
opentela/internal/metrics/scraper.go:166:			scrapeTarget			84.6%
opentela/internal/metrics/scraper.go:189:			parseMetrics			84.6%
opentela/internal/metrics/scraper.go:210:			evictStale			85.7%
opentela/internal/platform/gpu.go:10:				GetGPUInfo			75.0%
opentela/internal/platform/gpu.go:18:				getNvidiaGPUs			26.3%
opentela/internal/platform/gpu.go:48:				getAMDGPUs			12.5%
opentela/internal/platform/gpu.go:117:				csvField			100.0%
opentela/internal/platform/slurm/env.go:10:			IsSlurm				100.0%
opentela/internal/platform/slurm/env.go:14:			getJobId			100.0%
opentela/internal/platform/slurm/env.go:18:			getNodeId			100.0%
opentela/internal/platform/slurm/env.go:22:			getRemainingTimeInSeconds	44.4%
opentela/internal/platform/slurm/env.go:43:			GetJobInfo			100.0%
opentela/internal/protocol/bootstrap.go:17:			getDefaultBootstrapPeers	77.8%
opentela/internal/protocol/bootstrap.go:49:			collectBootstrapSources		92.3%
opentela/internal/protocol/bootstrap.go:71:			resolveBootstrapSources		90.0%
opentela/internal/protocol/bootstrap.go:88:			resolveBootstrapSource		85.7%
opentela/internal/protocol/bootstrap.go:104:			fetchHTTPBootstraps		80.0%
opentela/internal/protocol/bootstrap.go:120:			fetchDNSAddrBootstraps		77.8%
opentela/internal/protocol/bootstrap.go:147:			expandBootstrapValue		54.5%
opentela/internal/protocol/bootstrap.go:167:			splitBootstrapValue		100.0%
opentela/internal/protocol/bootstrap.go:174:			parseBootstrapMultiaddrs	75.0%
opentela/internal/protocol/clock.go:20:				StartTicker			0.0%
opentela/internal/protocol/crdt.go:33:				GetCRDTStore			0.0%
opentela/internal/protocol/crdt.go:183:				Reconnect			0.0%
opentela/internal/protocol/crdt.go:199:				ClearCRDTStore			0.0%
opentela/internal/protocol/go-ds-crdt/compaction.go:16:		decodeTombstoneTimestamp	0.0%
opentela/internal/protocol/go-ds-crdt/compaction.go:32:		CompactTombstones		0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:114:		verify				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:147:		DefaultOptions			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:231:		New				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:370:		handleNext			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:461:		decodeBroadcast			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:492:		encodeBroadcast			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:501:		randomizeInterval		0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:510:		rebroadcast			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:527:		repair				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:555:		rebroadcastHeads		0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:588:		logStats			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:614:		handleBlock			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:632:		handleBranch			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:650:		dagWorker			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:690:		sendNewJobs			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:775:		sendJobWorker			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:791:		processedBlockKey		0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:795:		isProcessed			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:799:		markProcessed			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:803:		dirtyKey			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:808:		MarkDirty			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:817:		IsDirty				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:826:		MarkClean			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:836:		processNode			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:959:		repairDAG			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1072:		Repair				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1078:		Get				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1086:		Has				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1093:		GetSize				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1108:		Query				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1117:		Put				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1123:		Delete				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1137:		Sync				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1181:		Context				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1186:		Close				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1198:		Batch				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1202:		deltaMerge			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1215:		addToDelta			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1221:		rmvToDelta			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1232:		updateDeltaWithRemove		0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1254:		updateDelta			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1265:		publishDelta			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1276:		putBlock			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1295:		publish				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1307:		addDAGNode			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1349:		broadcast			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1383:		Put				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1395:		Delete				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1409:		Commit				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1415:		PrintDAG			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1434:		printDAGRec			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1495:		DotDAG				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1523:		dotDAGRec			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1576:		InternalStats			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1591:		newCidSafeSet			0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1597:		Visit				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1610:		Remove				0.0%
opentela/internal/protocol/go-ds-crdt/crdt.go:1618:		Has				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:29:		newHeads			0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:42:		key				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:47:		write				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:56:		delete				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:68:		IsHead				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:79:		Len				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:90:		Replace				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:134:		Add				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:149:		List				0.0%
opentela/internal/protocol/go-ds-crdt/heads.go:176:		primeCache			0.0%
opentela/internal/protocol/go-ds-crdt/ipld.go:23:		GetDelta			0.0%
opentela/internal/protocol/go-ds-crdt/ipld.go:33:		GetPriority			0.0%
opentela/internal/protocol/go-ds-crdt/ipld.go:48:		GetDeltas			0.0%
opentela/internal/protocol/go-ds-crdt/ipld.go:72:		extractDelta			0.0%
opentela/internal/protocol/go-ds-crdt/ipld.go:82:		makeNode			0.0%
opentela/internal/protocol/go-ds-crdt/migrations.go:18:		versionKey			0.0%
opentela/internal/protocol/go-ds-crdt/migrations.go:22:		getVersion			0.0%
opentela/internal/protocol/go-ds-crdt/migrations.go:39:		setVersion			0.0%
opentela/internal/protocol/go-ds-crdt/migrations.go:50:		applyMigrations			0.0%
opentela/internal/protocol/go-ds-crdt/migrations.go:81:		migrate0to1			0.0%
opentela/internal/protocol/go-ds-crdt/pubsub_broadcaster.go:28:	NewPubSubBroadcaster		0.0%
opentela/internal/protocol/go-ds-crdt/pubsub_broadcaster.go:60:	Broadcast			0.0%
opentela/internal/protocol/go-ds-crdt/pubsub_broadcaster.go:65:	Next				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:50:		newCRDTSet			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:73:		Add				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:86:		Rmv				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:133:		Element				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:150:		Elements			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:251:		InSet				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:259:		keyPrefix			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:264:		elemsPrefix			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:269:		tombsPrefix			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:274:		valueKey			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:279:		priorityKey			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:283:		getPriority			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:300:		setPriority			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:313:		setValue			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:359:		findBestValue			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:464:		putElems			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:510:		putTombs			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:584:		Merge				0.0%
opentela/internal/protocol/go-ds-crdt/set.go:599:		inTombsKeyID			0.0%
opentela/internal/protocol/go-ds-crdt/set.go:620:		datastoreSync			0.0%
opentela/internal/protocol/host.go:53:				GetP2PNode			0.0%
opentela/internal/protocol/host.go:78:				registerPingProtocol		100.0%
opentela/internal/protocol/host.go:82:				newHost				0.0%
opentela/internal/protocol/host.go:314:				StartAutoReconnect		0.0%
opentela/internal/protocol/host.go:322:				startAutoReconnect		0.0%
opentela/internal/protocol/host.go:375:				tryReconnectToBootstraps	0.0%
opentela/internal/protocol/host.go:431:				waitFor				100.0%
opentela/internal/protocol/host.go:447:				backoffDelay			77.8%
opentela/internal/protocol/host.go:463:				backoffBaseDelay		90.0%
opentela/internal/protocol/host.go:483:				isTransientNetworkError		87.5%
opentela/internal/protocol/host.go:500:				relayServiceResources		0.0%
opentela/internal/protocol/host.go:509:				newResourceManager		0.0%
opentela/internal/protocol/host.go:519:				newDHT				0.0%
opentela/internal/protocol/host.go:533:				ConnectedPeers			0.0%
opentela/internal/protocol/host.go:548:				AllPeers			0.0%
opentela/internal/protocol/host.go:562:				BuildBootstrapAddr		85.7%
opentela/internal/protocol/host.go:574:				buildPublicTCPMultiaddr		66.7%
opentela/internal/protocol/host.go:587:				publicAddrHostAndProtocol	78.6%
opentela/internal/protocol/host.go:613:				appendUniqueMultiaddrs		88.2%
opentela/internal/protocol/host.go:645:				isRecentRelayPeer		100.0%
opentela/internal/protocol/host.go:654:				ConnectedBootstraps		0.0%
opentela/internal/protocol/host.go:694:				MakeRelayReservations		0.0%
opentela/internal/protocol/host.go:732:				IsDirectlyConnected		0.0%
opentela/internal/protocol/host.go:748:				FindRelayFor			0.0%
opentela/internal/protocol/host.go:785:				GetResourceManagerStats		0.0%
opentela/internal/protocol/key.go:16:				ResolveKeyPath			83.3%
opentela/internal/protocol/key.go:30:				WriteKeyToFile			0.0%
opentela/internal/protocol/key.go:56:				LoadKeyFromFile			0.0%
opentela/internal/protocol/key.go:80:				GenerateAndWriteKey		0.0%
opentela/internal/protocol/node_table.go:34:			InitScalableNodeTable		0.0%
opentela/internal/protocol/node_table.go:42:			GetScalableSnapshot		0.0%
opentela/internal/protocol/node_table.go:49:			GetNodeTableWriter		0.0%
opentela/internal/protocol/node_table.go:55:			StartSWIM			0.0%
opentela/internal/protocol/node_table.go:211:			getNodeTable			100.0%
opentela/internal/protocol/node_table.go:218:			UpdateNodeTable			0.0%
opentela/internal/protocol/node_table.go:253:			MarkSelfAsBootstrap		0.0%
opentela/internal/protocol/node_table.go:279:			AnnounceLeave			0.0%
opentela/internal/protocol/node_table.go:304:			UpdateNodeTableHook		70.5%
opentela/internal/protocol/node_table.go:381:			DeleteNodeTableHook		100.0%
opentela/internal/protocol/node_table.go:388:			GetPeerFromTable		100.0%
opentela/internal/protocol/node_table.go:399:			GetConnectedPeers		0.0%
opentela/internal/protocol/node_table.go:411:			GetAllPeers			100.0%
opentela/internal/protocol/node_table.go:421:			GetService			0.0%
opentela/internal/protocol/node_table.go:438:			GetAllProviders			0.0%
opentela/internal/protocol/node_table.go:466:			InitializeMyself		0.0%
opentela/internal/protocol/node_table.go:555:			GetSelf				100.0%
opentela/internal/protocol/node_table.go:562:			SetMyselfRelayPeer		0.0%
opentela/internal/protocol/node_table.go:569:			SetMyselfForTest		100.0%
opentela/internal/protocol/node_table.go:577:			RegisterRemotePeer		0.0%
opentela/internal/protocol/nodetable/snapshot.go:55:		NewNodeTable			100.0%
opentela/internal/protocol/nodetable/snapshot.go:62:		Snapshot			100.0%
opentela/internal/protocol/nodetable/snapshot.go:67:		Store				100.0%
opentela/internal/protocol/nodetable/snapshot.go:72:		NewSnapshot			100.0%
opentela/internal/protocol/nodetable/snapshot.go:84:		Clone				100.0%
opentela/internal/protocol/nodetable/snapshot.go:100:		ApplyEvent			71.7%
opentela/internal/protocol/nodetable/snapshot.go:187:		RebuildIndexes			91.7%
opentela/internal/protocol/nodetable/writer.go:33:		init				100.0%
opentela/internal/protocol/nodetable/writer.go:52:		NewWriter			100.0%
opentela/internal/protocol/nodetable/writer.go:60:		Start				100.0%
opentela/internal/protocol/nodetable/writer.go:65:		Stop				100.0%
opentela/internal/protocol/nodetable/writer.go:71:		Send				100.0%
opentela/internal/protocol/nodetable/writer.go:79:		run				100.0%
opentela/internal/protocol/nodetable/writer.go:109:		drainAndApply			66.7%
opentela/internal/protocol/nodetable/writer.go:123:		applyBatch			100.0%
opentela/internal/protocol/registrar.go:25:			addLocalService			100.0%
opentela/internal/protocol/registrar.go:54:			snapshotLocalServices		100.0%
opentela/internal/protocol/registrar.go:62:			RegisterLocalServices		0.0%
opentela/internal/protocol/registrar.go:96:			healthCheckRemote		0.0%
opentela/internal/protocol/registrar.go:120:			registerLLMService		0.0%
opentela/internal/protocol/registrar.go:147:			provideService			0.0%
opentela/internal/protocol/registrar.go:173:			ReannounceLocalServices		0.0%
opentela/internal/protocol/swim/dissemination.go:23:		NewDisseminator			66.7%
opentela/internal/protocol/swim/dissemination.go:35:		UpdateN				100.0%
opentela/internal/protocol/swim/dissemination.go:44:		retransmitLimit			100.0%
opentela/internal/protocol/swim/dissemination.go:50:		Enqueue				88.9%
opentela/internal/protocol/swim/dissemination.go:73:		GetPiggyback			93.3%
opentela/internal/protocol/swim/dissemination.go:100:		statusPriority			50.0%
opentela/internal/protocol/swim/messages.go:58:			MarshalJSON			100.0%
opentela/internal/protocol/swim/messages.go:67:			UnmarshalJSON			87.5%
opentela/internal/protocol/swim/messages.go:87:			Marshal				28.6%
opentela/internal/protocol/swim/messages.go:109:		Unmarshal			100.0%
opentela/internal/protocol/swim/messages.go:129:		Marshal				80.0%
opentela/internal/protocol/swim/messages.go:149:		Unmarshal			76.9%
opentela/internal/protocol/swim/metrics.go:30:			init				100.0%
opentela/internal/protocol/swim/swim.go:72:			NewSWIM				100.0%
opentela/internal/protocol/swim/swim.go:86:			AddMember			100.0%
opentela/internal/protocol/swim/swim.go:97:			RemoveMember			100.0%
opentela/internal/protocol/swim/swim.go:107:			GetStatus			100.0%
opentela/internal/protocol/swim/swim.go:117:			GetIncarnation			100.0%
opentela/internal/protocol/swim/swim.go:124:			Members				100.0%
opentela/internal/protocol/swim/swim.go:136:			probeOnce			86.7%
opentela/internal/protocol/swim/swim.go:168:			processPendingProbes		94.2%
opentela/internal/protocol/swim/swim.go:273:			processSuspects			100.0%
opentela/internal/protocol/swim/swim.go:314:			HandleMessage			100.0%
opentela/internal/protocol/swim/swim.go:366:			processEvents			27.8%
opentela/internal/protocol/swim/swim.go:437:			Run				100.0%
opentela/internal/protocol/swim/swim.go:460:			updateMemberGauge		100.0%
opentela/internal/protocol/swim/swim.go:475:			Close				75.0%
opentela/internal/protocol/swim/transport.go:27:		NewLibP2PTransport		0.0%
opentela/internal/protocol/swim/transport.go:31:		send				0.0%
opentela/internal/protocol/swim/transport.go:49:		SendPing			0.0%
opentela/internal/protocol/swim/transport.go:53:		SendAck				0.0%
opentela/internal/protocol/swim/transport.go:57:		SendPingReq			0.0%
opentela/internal/protocol/swim/transport.go:62:		RegisterHandler			0.0%
opentela/internal/protocol/tombstone_compactor.go:21:		startTombstoneCompactor		0.0%
opentela/internal/protocol/tombstone_compactor.go:91:		readDurationSetting		100.0%
opentela/internal/protocol/tombstone_manager.go:24:		GetTombstoneManager		0.0%
opentela/internal/protocol/tombstone_manager.go:37:		CleanupLeftNodes		87.5%
opentela/internal/protocol/tombstone_manager.go:58:		collectCandidates		100.0%
opentela/internal/server/access_control.go:46:			resolveCallerWallet		18.2%
opentela/internal/server/access_control.go:73:			accessControlMiddleware		73.5%
opentela/internal/server/access_control.go:147:			isLibp2pRemoteAddr		100.0%
opentela/internal/server/access_control.go:153:			containsWallet			100.0%
opentela/internal/server/auth_client.go:41:			get				100.0%
opentela/internal/server/auth_client.go:51:			set				100.0%
opentela/internal/server/auth_client.go:64:			verifyBearerToken		83.3%
opentela/internal/server/auth_client.go:107:			resolveClientWallet		75.0%
opentela/internal/server/cors.go:10:				corsHeader			100.0%
opentela/internal/server/cors.go:26:				rewriteHeader			100.0%
opentela/internal/server/crdt_handler.go:12:			listPeers			100.0%
opentela/internal/server/crdt_handler.go:17:			listPeersWithStatus		100.0%
opentela/internal/server/crdt_handler.go:23:			listBootstraps			0.0%
opentela/internal/server/crdt_handler.go:28:			getResourceStats		100.0%
opentela/internal/server/crdt_handler.go:45:			updateLocal			0.0%
opentela/internal/server/crdt_handler.go:55:			deleteLocal			0.0%
opentela/internal/server/crdt_handler.go:64:			getDNT				0.0%
opentela/internal/server/health.go:9:				healthStatusCheck		100.0%
opentela/internal/server/ingest.go:38:				getIngestStats			88.9%
opentela/internal/server/libp2p_http_transport.go:35:		newLibp2pHTTPRoundTripper	0.0%
opentela/internal/server/libp2p_http_transport.go:66:		RoundTrip			0.0%
opentela/internal/server/libp2p_http_transport.go:83:		CloseIdleConnections		0.0%
opentela/internal/server/p2p_listener.go:11:			P2PListener			0.0%
opentela/internal/server/probe_handler.go:24:			echoHandler			91.7%
opentela/internal/server/probe_handler.go:59:			Read				100.0%
opentela/internal/server/probe_handler.go:83:			runHandler			75.0%
opentela/internal/server/probe_handler.go:129:			runLatency			0.0%
opentela/internal/server/probe_handler.go:163:			summariseDurations		92.3%
opentela/internal/server/probe_handler.go:194:			runThroughput			0.0%
opentela/internal/server/probe_handler.go:260:			runLibp2pPing			0.0%
opentela/internal/server/probe_handler.go:281:			processPingResults		100.0%
opentela/internal/server/proxy_handler.go:64:			init				100.0%
opentela/internal/server/proxy_handler.go:68:			getGlobalTransport		0.0%
opentela/internal/server/proxy_handler.go:83:			ErrorHandler			0.0%
opentela/internal/server/proxy_handler.go:95:			WriteHeader			0.0%
opentela/internal/server/proxy_handler.go:105:			Flush				0.0%
opentela/internal/server/proxy_handler.go:112:			P2PForwardHandler		0.0%
opentela/internal/server/proxy_handler.go:150:			ServiceForwardHandler		0.0%
opentela/internal/server/proxy_handler.go:186:			parseFallbackLevel		100.0%
opentela/internal/server/proxy_handler.go:205:			selectCandidates		100.0%
opentela/internal/server/proxy_handler.go:280:			weightedRandomSelect		81.2%
opentela/internal/server/proxy_handler.go:310:			scoreCandidates			0.0%
opentela/internal/server/proxy_handler.go:322:			excludePeers			100.0%
opentela/internal/server/proxy_handler.go:336:			shouldShedLoad			100.0%
opentela/internal/server/proxy_handler.go:345:			filterByTrust			0.0%
opentela/internal/server/proxy_handler.go:360:			GlobalServiceForwardHandler	0.0%
opentela/internal/server/ratelimit.go:27:			newRateLimiterStore		100.0%
opentela/internal/server/ratelimit.go:37:			getLimiter			100.0%
opentela/internal/server/ratelimit.go:51:			cleanup				57.1%
opentela/internal/server/ratelimit.go:66:			rateLimitMiddleware		88.9%
opentela/internal/server/registration.go:52:			challengePeer			81.8%
opentela/internal/server/registration.go:77:			registerPeer			37.9%
opentela/internal/server/registration.go:227:			StartChallengeCleanup		0.0%
opentela/internal/server/registration.go:236:			cleanExpiredChallenges		0.0%
opentela/internal/server/retry_writer.go:38:			newRetryableResponseWriter	100.0%
opentela/internal/server/retry_writer.go:54:			Header				100.0%
opentela/internal/server/retry_writer.go:59:			markFailed			100.0%
opentela/internal/server/retry_writer.go:65:			isRetryable			100.0%
opentela/internal/server/retry_writer.go:71:			commitHeaders			87.5%
opentela/internal/server/retry_writer.go:87:			isStreamingResponse		100.0%
opentela/internal/server/retry_writer.go:99:			WriteHeader			87.5%
opentela/internal/server/retry_writer.go:123:			Write				91.7%
opentela/internal/server/retry_writer.go:154:			Flush				100.0%
opentela/internal/server/retry_writer.go:163:			flushToClient			100.0%
opentela/internal/server/self_handler.go:14:			isLoopback			80.0%
opentela/internal/server/self_handler.go:24:			getSelf				100.0%
opentela/internal/server/self_handler.go:34:			signData			10.7%
opentela/internal/server/server.go:23:				StartServer			0.0%
opentela/internal/server/tracer.go:20:				initTracer			0.0%
opentela/internal/server/tracer.go:44:				IngestEvents			0.0%
opentela/internal/solana/client.go:27:				NewClient			100.0%
opentela/internal/solana/client.go:55:				call				88.2%
opentela/internal/solana/client.go:93:				HasSPLToken			100.0%
opentela/internal/solana/client.go:141:				GetBalance			88.9%
opentela/internal/solana/client.go:159:				GetBalanceSOL			75.0%
opentela/internal/solana/client.go:173:				GetTokenBalance			73.3%
opentela/internal/solana/client.go:215:				RequestAirdrop			77.8%
opentela/internal/solana/client.go:253:				SendSOL				0.0%
opentela/internal/solana/client.go:309:				getRecentBlockhash		0.0%
opentela/internal/solana/client.go:336:				buildTransferMessage		100.0%
opentela/internal/solana/client.go:387:				serializeTransaction		100.0%
opentela/internal/solana/processor.go:45:			NewPaymentProcessor		83.3%
opentela/internal/solana/processor.go:72:			ProcessUsageRecords		0.0%
opentela/internal/solana/processor.go:134:			submitPayment			0.0%
opentela/internal/solana/processor.go:223:			confirmTransaction		0.0%
opentela/internal/solana/processor.go:247:			VerifyBalance			0.0%
opentela/internal/solana/rates.go:30:				NewRateManager			100.0%
opentela/internal/solana/rates.go:38:				rateKey				100.0%
opentela/internal/solana/rates.go:44:				GetRate				100.0%
opentela/internal/solana/rates.go:72:				SetRate				100.0%
opentela/internal/solana/rates.go:79:				LoadFromConfig			87.5%
opentela/internal/solana/settlement.go:22:			SubmitSettlement		7.3%
opentela/internal/solana/spl.go:26:				FindATA				85.7%
opentela/internal/solana/spl.go:42:				findProgramAddress		57.1%
opentela/internal/solana/spl.go:57:				createProgramAddress		88.9%
opentela/internal/solana/spl.go:88:				isOnCurve			100.0%
opentela/internal/solana/spl.go:98:				BuildSPLTransferChecked		100.0%
opentela/internal/solana/spl.go:155:				BuildCreateATAInstruction	100.0%
opentela/internal/solana/spl.go:208:				SendSPLTransfer			0.0%
opentela/internal/solana/spl.go:249:				CreateATA			0.0%
opentela/internal/solana/spl.go:292:				GetSignatureStatus		0.0%
opentela/internal/solana/spl.go:331:				mustDecodeBase58		75.0%
opentela/internal/usage/aggregator.go:31:			NewAggregator			100.0%
opentela/internal/usage/aggregator.go:39:			AddRecord			100.0%
opentela/internal/usage/aggregator.go:59:			ShouldFlush			92.3%
opentela/internal/usage/aggregator.go:86:			BuildAggregate			88.9%
opentela/internal/usage/aggregator.go:114:			GetValue			83.3%
opentela/internal/usage/aggregator.go:127:			SetWindowStart			83.3%
opentela/internal/usage/crdt.go:13:				PublishAggregate		0.0%
opentela/internal/usage/crdt.go:27:				GetPeerAggregate		0.0%
opentela/internal/usage/crdt.go:46:				getAggregateKey			100.0%
opentela/internal/usage/extractor.go:15:			ExtractUsageMetrics		93.8%
opentela/internal/usage/reconciler.go:11:			ReconcileRecords		92.6%
opentela/internal/usage/store.go:17:				NewUsageStore			83.3%
opentela/internal/usage/store.go:30:				Close				100.0%
opentela/internal/usage/store.go:35:				SaveRecord			83.3%
opentela/internal/usage/store.go:49:				GetRecord			100.0%
opentela/internal/usage/store.go:73:				GetPendingRecords		88.9%
opentela/internal/usage/store.go:114:				MarkAggregated			83.3%
opentela/internal/usage/store.go:127:				SaveAggregate			83.3%
opentela/internal/usage/tracker.go:28:				InitTracker			0.0%
opentela/internal/usage/tracker.go:54:				CloseTracker			0.0%
opentela/internal/usage/tracker.go:62:				Track				0.0%
opentela/internal/usage/tracker.go:89:				GenerateRequestID		100.0%
opentela/internal/wallet/identity.go:35:			SignIdentity			75.0%
opentela/internal/wallet/identity.go:67:			VerifyIdentity			77.8%
opentela/internal/wallet/wallet.go:67:				NewWalletManager		66.7%
opentela/internal/wallet/wallet.go:98:				NewWalletManagerWithDir		66.7%
opentela/internal/wallet/wallet.go:116:				loadAccounts			94.4%
opentela/internal/wallet/wallet.go:151:				migrateLegacyWallet		87.5%
opentela/internal/wallet/wallet.go:186:				migrateLegacyDir		82.9%
opentela/internal/wallet/wallet.go:254:				saveAccounts			71.4%
opentela/internal/wallet/wallet.go:275:				Accounts			100.0%
opentela/internal/wallet/wallet.go:282:				DefaultAccount			100.0%
opentela/internal/wallet/wallet.go:291:				AddSolanaAccount		73.3%
opentela/internal/wallet/wallet.go:325:				ImportSolanaKeypair		81.8%
opentela/internal/wallet/wallet.go:375:				ExportKeypair			77.8%
opentela/internal/wallet/wallet.go:394:				ExportBase58PrivateKey		85.7%
opentela/internal/wallet/wallet.go:413:				FindByFile			100.0%
opentela/internal/wallet/wallet.go:423:				FindByPublicKey			100.0%
opentela/internal/wallet/wallet.go:433:				FindByProviderID		100.0%
opentela/internal/wallet/wallet.go:443:				WalletExists			100.0%
opentela/internal/wallet/wallet.go:451:				GetPublicKey			100.0%
opentela/internal/wallet/wallet.go:458:				GetPrivateKey			100.0%
opentela/internal/wallet/wallet.go:465:				GetWalletPath			100.0%
opentela/internal/wallet/wallet.go:472:				GetWalletType			100.0%
opentela/internal/wallet/wallet.go:481:				GetProviderID			100.0%
opentela/internal/wallet/wallet.go:490:				GetPrivateKeyBytes		77.8%
opentela/internal/wallet/wallet.go:510:				InitializeWallet		83.3%
opentela/internal/wallet/wallet.go:527:				writeSolanaKeypair		77.8%
opentela/internal/wallet/wallet.go:544:				parseSolanaKeypairJSON		100.0%
opentela/internal/wallet/wallet.go:565:				deriveProviderID		100.0%
opentela/internal/wallet/wallet.go:574:				copyDirRecursive		76.9%
opentela/plugins/webui/embed.go:12:				Static				0.0%
total:								(statements)			36.9%

Summary:

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an OpenTela-native “mesh bench” capability by introducing new probe endpoints and CLI commands in the Go binary, plus a new Python-based contrib/network-profiler tool that can orchestrate pairwise latency/throughput measurements across a set of machines.

Changes:

  • Added /v1/probe/echo and /v1/probe/run endpoints and a keep-alive libp2p HTTP RoundTripper to support efficient HTTP-over-libp2p measurements.
  • Added otela probe and otela peer-id commands plus config/key-path handling updates to support bench orchestration.
  • Added a new Python network-profiler package with a bench workflow (init/discover/configure/push/start/converge/sweep/teardown), tests, and documentation.

Reviewed changes

Copilot reviewed 43 out of 45 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/internal/server/server.go Registers new /v1/probe routes and swaps libp2p transport registration to the new RoundTripper.
src/internal/server/proxy_handler.go Uses the new libp2p HTTP RoundTripper for libp2p:// traffic.
src/internal/server/probe_handler.go Implements echo + probe execution endpoints (latency/throughput/libp2p ping).
src/internal/server/probe_handler_test.go Adds unit tests for probe handler helpers and endpoints.
src/internal/server/libp2p_http_transport.go Adds a custom RoundTripper to enable stdlib keep-alive pooling over libp2p streams.
src/internal/protocol/key.go Adds ResolveKeyPath, exports key load/write helpers, and adds GenerateAndWriteKey.
src/internal/protocol/key_test.go Adds tests for key path resolution behavior.
src/internal/protocol/host.go Registers ping protocol and changes relay/autorelay configuration + relay resource settings.
src/internal/protocol/host_test.go Adds a test that verifies the ping protocol is registered.
src/entry/cmd/root.go Adds --config-dir persistent flag and ensures seeding honors the configured path.
src/entry/cmd/root_test.go Updates config seeding tests and adds a regression test for --config-dir seeding.
src/entry/cmd/init.go Adds libp2p key initialization during otela init.
src/entry/cmd/init_test.go Tests libp2p key creation/idempotence for otela init flow.
src/entry/cmd/probe.go Adds otela probe command to call the local node’s /v1/probe/run.
src/entry/cmd/probe_test.go Adds tests for the probe CLI behavior against an httptest server.
src/entry/cmd/peerid.go Adds otela peer-id command to print PeerID derived from the on-disk key.
src/entry/cmd/peerid_test.go Adds a test for the peer-id command output shape.
meta/build_core_docker.sh Hardens script execution and adds build signing key handling with BuildKit secrets.
deploy/tds/opentela.yaml Updates the deployment image reference to an amd64-tagged image.
docs/content/docs/proposals/meta.json Adds the mesh-bench design proposal to proposals index.
docs/content/docs/proposals/2026-05-02-mesh-bench-design.mdx Adds the mesh-bench design proposal document.
docs/content/docs/advanced/security.mdx Updates security documentation text.
docs/content/docs/advanced/network-profiling.mdx Adds end-user docs for baseline profiling and OpenTela-native bench workflow.
docs/content/docs/advanced/meta.json Adds the new network profiling page to the advanced docs index.
contrib/network-profiler/pyproject.toml Introduces Python package metadata and pytest configuration.
contrib/network-profiler/uv.lock Adds dependency lockfile for the Python tool.
contrib/network-profiler/network_profiler/init.py Adds package init + version.
contrib/network-profiler/network_profiler/main.py Adds module entrypoint.
contrib/network-profiler/network_profiler/cli.py Implements CLI with plan, collect, heatmap, and new bench command.
contrib/network-profiler/network_profiler/model.py Adds config/machine models and JSON config loading.
contrib/network-profiler/network_profiler/remote.py Adds command template expansion and remote execution wrapper.
contrib/network-profiler/network_profiler/measure.py Implements baseline ping/iperf collection + JSONL recording.
contrib/network-profiler/network_profiler/render.py Adds HTML heatmap rendering from JSONL measurements.
contrib/network-profiler/network_profiler/bench_config.py Builds per-host bench cfg.yaml including bootstrap multiaddrs and ports.
contrib/network-profiler/network_profiler/bench.py Implements bench orchestration phases + JSONL/run.json output.
contrib/network-profiler/tests/test_remote.py Adds tests for remote command templating and stdin support.
contrib/network-profiler/tests/test_measure.py Adds tests for ping/iperf parsing.
contrib/network-profiler/tests/test_bench_cli.py Adds tests that bench is wired into the CLI.
contrib/network-profiler/tests/test_bench_config.py Adds tests for multiaddr and bench config generation.
contrib/network-profiler/tests/test_bench_phases.py Adds tests for bench phase behaviors and record writing.
contrib/network-profiler/tests/test_bench_smoke.py Adds a local two-node smoke test for the end-to-end bench workflow.
contrib/network-profiler/README.md Adds usage and configuration documentation for the Python tool.
contrib/network-profiler/Makefile Adds test and bench-smoke targets.
contrib/network-profiler/.gitignore Ignores Python caches and results/.
.gitignore Adds .claude/ to ignored paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/entry/cmd/init.go
return err
}
if _, err := os.Stat(keyPath); err == nil {
return nil
Comment on lines +163 to +166
libp2p.EnableRelayService(
relayv2.WithResources(relayServiceResources()),
relayv2.WithInfiniteLimits(),
),
Comment on lines +217 to +221
probeGroup := v1.Group("/probe")
{
probeGroup.GET("/echo", echoHandler)
probeGroup.POST("/run", runHandler)
}
Comment on lines +147 to +151
resp, err := client.Do(req)
if err != nil {
failed++
lastErr = err.Error()
continue
Comment on lines +22 to +26
const maxEchoBytes = 1 << 30 // 1 GiB hard cap

func echoHandler(c *gin.Context) {
raw := c.Query("bytes")
if raw == "" {

## OpenTela-native: `net-profiler bench`

The bench owns the full lifecycle: it brings up an isolated four-port mesh on each host, runs every (source, destination) pair through three probe kinds, and tears the mesh down. Each run uses a unique config dir at `/tmp/otela-bench-<runID>-<host>/` so it never collides with persistent OpenTela state.
Comment on lines +361 to +362
"http_port": http_port,
"libp2p_port": libp2p_port,
Comment on lines +215 to +219
resp, err := client.Do(req)
if err != nil {
failed++
lastErr = err.Error()
continue
Comment on lines +221 to +225
bytesRead, copyErr := io.Copy(io.Discard, resp.Body)
resp.Body.Close()
elapsed := time.Since(start).Nanoseconds()
if copyErr != nil {
failed++
Comment on lines +135 to +139
func TestRunThroughput_AggregateIsBandwidthWeighted(t *testing.T) {
// Two iterations, equal bytes, very different elapsed times.
// Per-iteration mbps: 80 and 8. Mean = 44 mbps.
// Bandwidth-weighted: total_bytes=2*1MB=16Mbits, total_elapsed=0.1+1.0=1.1s = 16/1.1 ≈ 14.55 mbps.
// The aggregate should be the bandwidth-weighted number.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants