Skip to content

test(smoke): share one daemon across read-only RPC query tests (#999)#1007

Merged
oskarszoon merged 5 commits into
bsv-blockchain:mainfrom
oskarszoon:fix/test-daemon-shared
Jun 1, 2026
Merged

test(smoke): share one daemon across read-only RPC query tests (#999)#1007
oskarszoon merged 5 commits into
bsv-blockchain:mainfrom
oskarszoon:fix/test-daemon-shared

Conversation

@oskarszoon

Copy link
Copy Markdown
Contributor

Summary

Collapses the 8 read-only RPC query tests in test/e2e/daemon/ready/smoke_test.go into one shared-daemon parent TestRPCQueries with t.Run subtests. Was 8 full in-process daemons + 8 Aerospike TestContainers; now 1 of each for the group.

  • Fixture chain is mined once; the 7 read-only subtests query it. The only mutating subtest (GetRawTransactionVerbose — broadcasts a tx spending the fixture coinbase) runs last, so it can't affect the reads.
  • Assertions are carried over verbatim — no change to what's tested. No production code touched; only smoke_test.go.
  • For this group: 23 → 16 daemon starts and 21 → 14 Aerospike container starts in smoke_test.go.

Scope / correction

This is the smoke-query-group slice of #999, not the whole issue.

Worth flagging: #999 (and #997) attribute the per-start cost to StartBlockchainService in test/nodeHelpers/blockchainDaemon.go. The gated ready e2e tests don't use that helper — they use daemon.NewTestDaemon. PR #1000 fixed nodeHelpers/blockchainDaemon.go (used by the blockassembly system tests) and is orthogonal; it does not speed up these e2e tests. The real cost here is NewTestDaemon + per-test Aerospike container churn, which this PR cuts.

The other #999 files (legacy_sync, reorg, banlist) are multi-node or state-mutating with no state-safe shared subset, so they're left as-is.

Test Plan

  • go build ./... && go vet ./test/e2e/daemon/ready/... — clean
  • go test -count=1 -race -run TestRPCQueries -v . — all 8 subtests PASS; exactly 1 Aerospike container init (was 8)
  • spot-ran untouched TestSendTxAndCheckState + TestGenerateToAddress — PASS

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete

Summary

This PR successfully consolidates 8 separate read-only RPC test functions into a single parent test with subtests, reducing resource usage from 8 daemon instances + 8 Aerospike containers to just 1 of each for the group. The refactoring is well-designed and follows sound testing principles.

Key Strengths

  1. Fixture sharing is safe: The fixture chain is mined once upfront. All read-only subtests (Version, GetPeerInfo, GetBestBlockHash, GetMiningInfo, GetBlockVerbosity, GetBlockHeaderVerbose, GetMiningCandidate) query without mutation.

  2. Mutation ordering is correct: GetRawTransactionVerbose (the only mutating subtest) runs last and only performs an additive mutation by broadcasting a new transaction. It doesn't interfere with prior read tests.

  3. Assertions preserved: All test assertions are carried over verbatim from the original separate tests — no test coverage is lost.

  4. Clear documentation: Comments at lines 984-987 and 997-998 explicitly document the consolidation strategy and the CoinbaseMaturity assumption (verified correct in daemon/test_daemon.go:355).

  5. Aligns with project goals: Reduces test suite execution time and container churn, directly addressing issue Speed up gated e2e tests: share daemon fixtures (stop per-test daemon startup) #999.

No Issues Found

The refactoring is sound. Test isolation is preserved, shared state is read-only except for the final subtest, and all behavior is equivalent to the original implementation.

@ordishs ordishs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Clean, well-scoped test refactor. Verified locally:

  • go vet ./test/e2e/daemon/ready/... — clean
  • Subtest source order confirms the mutating GetRawTransactionVerbose runs last, after all read-only subtests — state-safety claim holds
  • No external references (CI/Makefile/scripts/other packages) to the 8 removed test names — rename breaks nothing
  • Assertions carried over 1:1 from the originals; only the read-only group consolidated

Tradeoffs are inherent to consolidation (coarser failure blast radius, finer -run granularity lost) and reasonable for read-only queries. PR description is accurate about scope vs #999/#1000.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-1007 (c9d2a11)

Summary

  • Regressions: 0
  • Improvements: 0
  • Unchanged: 144
  • Significance level: p < 0.05
All benchmark results (sec/op)
Benchmark Baseline Current Change p-value
_NewBlockFromBytes-4 1.773µ 1.769µ ~ 0.500
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 61.47n 61.95n ~ 0.100
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 61.76n 61.70n ~ 1.000
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 61.55n 61.46n ~ 0.400
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 32.29n 30.78n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 56.80n 52.94n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 119.6n 114.6n ~ 0.100
MiningCandidate_Stringify_Short-4 261.5n 261.3n ~ 0.400
MiningCandidate_Stringify_Long-4 1.919µ 1.953µ ~ 0.100
MiningSolution_Stringify-4 980.2n 980.6n ~ 0.400
BlockInfo_MarshalJSON-4 1.808µ 1.797µ ~ 0.100
NewFromBytes-4 130.5n 159.7n ~ 0.500
AddTxBatchColumnar_Validation-4 2.600µ 2.438µ ~ 0.200
OffsetValidationLoop-4 636.1n 635.8n ~ 1.000
Mine_EasyDifficulty-4 60.66µ 61.18µ ~ 0.100
Mine_WithAddress-4 6.958µ 7.179µ ~ 0.100
BlockAssembler_AddTx-4 0.02733n 0.02799n ~ 1.000
AddNode-4 11.46 11.31 ~ 0.700
AddNodeWithMap-4 10.89 12.11 ~ 0.100
DirectSubtreeAdd/4_per_subtree-4 61.75n 58.80n ~ 0.700
DirectSubtreeAdd/64_per_subtree-4 30.09n 30.07n ~ 1.000
DirectSubtreeAdd/256_per_subtree-4 28.78n 29.66n ~ 0.100
DirectSubtreeAdd/1024_per_subtree-4 27.92n 28.21n ~ 0.100
DirectSubtreeAdd/2048_per_subtree-4 27.53n 27.85n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 279.8n 282.5n ~ 1.000
SubtreeProcessorAdd/64_per_subtree-4 277.8n 280.2n ~ 1.000
SubtreeProcessorAdd/256_per_subtree-4 283.4n 282.1n ~ 1.000
SubtreeProcessorAdd/1024_per_subtree-4 277.8n 272.0n ~ 0.100
SubtreeProcessorAdd/2048_per_subtree-4 277.5n 271.5n ~ 0.100
SubtreeProcessorRotate/4_per_subtree-4 283.9n 277.7n ~ 0.100
SubtreeProcessorRotate/64_per_subtree-4 283.4n 275.4n ~ 0.100
SubtreeProcessorRotate/256_per_subtree-4 280.1n 274.8n ~ 0.100
SubtreeProcessorRotate/1024_per_subtree-4 280.8n 276.7n ~ 0.100
SubtreeNodeAddOnly/4_per_subtree-4 56.11n 54.50n ~ 0.100
SubtreeNodeAddOnly/64_per_subtree-4 34.86n 34.38n ~ 0.100
SubtreeNodeAddOnly/256_per_subtree-4 33.94n 33.38n ~ 0.100
SubtreeNodeAddOnly/1024_per_subtree-4 33.09n 32.72n ~ 0.100
SubtreeCreationOnly/4_per_subtree-4 118.7n 115.5n ~ 0.100
SubtreeCreationOnly/64_per_subtree-4 445.5n 413.5n ~ 0.100
SubtreeCreationOnly/256_per_subtree-4 1.476µ 1.396µ ~ 0.100
SubtreeCreationOnly/1024_per_subtree-4 4.881µ 4.435µ ~ 0.100
SubtreeCreationOnly/2048_per_subtree-4 8.717µ 8.401µ ~ 0.100
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 278.1n 281.4n ~ 0.100
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 277.4n 278.0n ~ 0.400
ParallelGetAndSetIfNotExists/1k_nodes-4 2.272m 2.225m ~ 0.100
ParallelGetAndSetIfNotExists/10k_nodes-4 5.666m 5.464m ~ 0.100
ParallelGetAndSetIfNotExists/50k_nodes-4 8.083m 7.367m ~ 0.100
ParallelGetAndSetIfNotExists/100k_nodes-4 10.68m 10.10m ~ 0.100
SequentialGetAndSetIfNotExists/1k_nodes-4 2.007m 1.958m ~ 0.200
SequentialGetAndSetIfNotExists/10k_nodes-4 4.912m 4.406m ~ 0.100
SequentialGetAndSetIfNotExists/50k_nodes-4 12.89m 12.41m ~ 0.100
SequentialGetAndSetIfNotExists/100k_nodes-4 23.21m 22.11m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 2.363m 2.245m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 8.590m 8.318m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 14.05m 13.10m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 2.014m 1.967m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 8.440m 7.461m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 44.41m 39.50m ~ 0.100
DiskTxMap_SetIfNotExists-4 3.783µ 3.459µ ~ 0.100
DiskTxMap_SetIfNotExists_Parallel-4 3.770µ 3.287µ ~ 0.200
DiskTxMap_ExistenceOnly-4 485.2n 319.0n ~ 0.100
Queue-4 198.9n 192.8n ~ 0.100
AtomicPointer-4 4.782n 4.984n ~ 0.400
ReorgOptimizations/DedupFilterPipeline/Old/10K-4 899.0µ 863.5µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/10K-4 819.3µ 799.3µ ~ 0.100
ReorgOptimizations/AllMarkFalse/Old/10K-4 110.1µ 107.5µ ~ 0.200
ReorgOptimizations/AllMarkFalse/New/10K-4 62.46µ 63.54µ ~ 0.100
ReorgOptimizations/HashSlicePool/Old/10K-4 69.70µ 69.85µ ~ 1.000
ReorgOptimizations/HashSlicePool/New/10K-4 11.52µ 11.52µ ~ 0.800
ReorgOptimizations/NodeFlags/Old/10K-4 5.736µ 4.833µ ~ 0.100
ReorgOptimizations/NodeFlags/New/10K-4 2.201µ 1.634µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/Old/100K-4 10.28m 10.03m ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/100K-4 10.62m 10.51m ~ 1.000
ReorgOptimizations/AllMarkFalse/Old/100K-4 1.162m 1.177m ~ 1.000
ReorgOptimizations/AllMarkFalse/New/100K-4 689.6µ 687.2µ ~ 1.000
ReorgOptimizations/HashSlicePool/Old/100K-4 636.1µ 562.7µ ~ 0.100
ReorgOptimizations/HashSlicePool/New/100K-4 291.1µ 301.5µ ~ 0.400
ReorgOptimizations/NodeFlags/Old/100K-4 50.75µ 52.68µ ~ 0.700
ReorgOptimizations/NodeFlags/New/100K-4 18.20µ 18.39µ ~ 0.400
TxMapSetIfNotExists-4 52.47n 52.38n ~ 0.800
TxMapSetIfNotExistsDuplicate-4 40.36n 40.61n ~ 0.700
ChannelSendReceive-4 605.3n 612.3n ~ 0.100
CalcBlockWork-4 490.2n 520.2n ~ 1.000
CalculateWork-4 666.2n 640.4n ~ 0.100
BuildBlockLocatorString_Helpers/Size_10-4 1.734µ 1.535µ ~ 0.700
BuildBlockLocatorString_Helpers/Size_100-4 13.16µ 13.42µ ~ 0.100
BuildBlockLocatorString_Helpers/Size_1000-4 131.0µ 131.1µ ~ 1.000
CatchupWithHeaderCache-4 104.8m 104.7m ~ 0.400
_prepareTxsPerLevel-4 412.7m 411.0m ~ 0.700
_prepareTxsPerLevelOrdered-4 3.695m 3.806m ~ 0.400
_prepareTxsPerLevel_Comparison/Original-4 420.7m 416.8m ~ 0.700
_prepareTxsPerLevel_Comparison/Optimized-4 3.820m 3.510m ~ 0.100
SubtreeSizes/10k_tx_4_per_subtree-4 1.358m 1.380m ~ 0.700
SubtreeSizes/10k_tx_16_per_subtree-4 325.8µ 332.3µ ~ 0.200
SubtreeSizes/10k_tx_64_per_subtree-4 78.81µ 79.51µ ~ 0.400
SubtreeSizes/10k_tx_256_per_subtree-4 19.28µ 19.84µ ~ 0.200
SubtreeSizes/10k_tx_512_per_subtree-4 9.507µ 9.850µ ~ 0.100
SubtreeSizes/10k_tx_1024_per_subtree-4 4.745µ 4.934µ ~ 0.100
SubtreeSizes/10k_tx_2k_per_subtree-4 2.395µ 2.468µ ~ 0.100
BlockSizeScaling/10k_tx_64_per_subtree-4 76.63µ 77.29µ ~ 0.200
BlockSizeScaling/10k_tx_256_per_subtree-4 19.31µ 19.52µ ~ 0.100
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.778µ 4.886µ ~ 0.100
BlockSizeScaling/50k_tx_64_per_subtree-4 408.0µ 408.6µ ~ 0.700
BlockSizeScaling/50k_tx_256_per_subtree-4 95.86µ 96.78µ ~ 0.100
BlockSizeScaling/50k_tx_1024_per_subtree-4 23.82µ 24.10µ ~ 0.100
SubtreeAllocations/small_subtrees_exists_check-4 163.6µ 161.8µ ~ 0.400
SubtreeAllocations/small_subtrees_data_fetch-4 170.9µ 169.9µ ~ 0.100
SubtreeAllocations/small_subtrees_full_validation-4 334.1µ 335.5µ ~ 1.000
SubtreeAllocations/medium_subtrees_exists_check-4 9.660µ 9.730µ ~ 0.200
SubtreeAllocations/medium_subtrees_data_fetch-4 10.09µ 10.25µ ~ 0.400
SubtreeAllocations/medium_subtrees_full_validation-4 19.57µ 19.85µ ~ 0.200
SubtreeAllocations/large_subtrees_exists_check-4 2.299µ 2.327µ ~ 0.100
SubtreeAllocations/large_subtrees_data_fetch-4 2.449µ 2.455µ ~ 1.000
SubtreeAllocations/large_subtrees_full_validation-4 4.888µ 4.970µ ~ 0.100
_BufferPoolAllocation/16KB-4 4.036µ 4.001µ ~ 0.200
_BufferPoolAllocation/32KB-4 8.452µ 9.003µ ~ 0.700
_BufferPoolAllocation/64KB-4 18.63µ 20.39µ ~ 0.700
_BufferPoolAllocation/128KB-4 34.18µ 38.02µ ~ 0.100
_BufferPoolAllocation/512KB-4 143.2µ 139.2µ ~ 0.200
_BufferPoolConcurrent/32KB-4 22.27µ 22.19µ ~ 0.400
_BufferPoolConcurrent/64KB-4 33.29µ 33.08µ ~ 1.000
_BufferPoolConcurrent/512KB-4 170.5µ 175.7µ ~ 0.200
_SubtreeDeserializationWithBufferSizes/16KB-4 687.6µ 735.4µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/32KB-4 684.0µ 734.6µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/64KB-4 684.1µ 739.3µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/128KB-4 687.7µ 743.5µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/512KB-4 666.1µ 722.3µ ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/16KB-4 38.43m 39.01m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/32KB-4 38.58m 38.85m ~ 0.200
_SubtreeDataDeserializationWithBufferSizes/64KB-4 38.30m 39.18m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/128KB-4 38.34m 38.84m ~ 0.400
_SubtreeDataDeserializationWithBufferSizes/512KB-4 38.89m 38.86m ~ 1.000
_PooledVsNonPooled/Pooled-4 818.5n 828.3n ~ 0.100
_PooledVsNonPooled/NonPooled-4 7.886µ 8.015µ ~ 0.700
_MemoryFootprint/Current_512KB_32concurrent-4 8.015µ 8.949µ ~ 0.100
_MemoryFootprint/Proposed_32KB_32concurrent-4 11.44µ 12.84µ ~ 0.100
_MemoryFootprint/Alternative_64KB_32concurrent-4 10.95µ 12.46µ ~ 0.100
StoreBlock_Sequential/BelowCSVHeight-4 310.6µ 308.7µ ~ 0.700
StoreBlock_Sequential/AboveCSVHeight-4 312.0µ 312.9µ ~ 0.400
GetUtxoHashes-4 257.4n 272.2n ~ 0.100
GetUtxoHashes_ManyOutputs-4 47.05µ 42.57µ ~ 0.100
_NewMetaDataFromBytes-4 229.5n 232.9n ~ 0.700
_Bytes-4 399.5n 395.7n ~ 0.200
_MetaBytes-4 138.4n 138.1n ~ 1.000

Threshold: >10% with p < 0.05 | Generated: 2026-06-01 15:37 UTC

@oskarszoon oskarszoon merged commit 55d3cc7 into bsv-blockchain:main Jun 1, 2026
36 of 37 checks passed
@sonarqubecloud

sonarqubecloud Bot commented Jun 1, 2026

Copy link
Copy Markdown

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.

3 participants