Skip to content

feat(ENG-5578): add integration tests with recorded market replay#127

Open
tvinagre wants to merge 31 commits into
mainfrom
tl/ENG-5578-integration-tests
Open

feat(ENG-5578): add integration tests with recorded market replay#127
tvinagre wants to merge 31 commits into
mainfrom
tl/ENG-5578-integration-tests

Conversation

@tvinagre
Copy link
Copy Markdown
Collaborator

Summary

  • Add record-market CLI tool that captures Tycho protocol stream updates and generates golden quote outputs by replaying through the full Fynd pipeline
  • Add integration test suite (fynd-core --test integration) that replays recorded fixtures and verifies solution availability, quality baselines, derived data, and timing
  • Worker pools and algorithm config loaded from worker_pools.toml to match production behavior
  • Golden file stores exact derived data metrics (spot prices, pool depths, token prices counts) for deterministic replay assertions
  • Shared golden types (GoldenFile, TestScenario, etc.) in fynd_core::recording::golden
  • parse_chain moved to fynd_core::types::constants for reuse across crates
  • Gas price captured from RPC as raw wei string (no lossy float conversion)
  • VM-backed protocol states (UniswapV4) filtered during recording serialization
  • Git LFS configured for compressed fixture files

Test plan

  • cargo +nightly fmt -- --check passes
  • cargo +nightly clippy --locked --all --all-features --all-targets -- -D warnings passes
  • cargo nextest run --workspace --locked --all-targets --all-features --bin fynd — 416 passed, 0 failed
  • All 8 integration tests pass (41/44 scenarios successful, 3 BNB pairs expected NoRouteFound)
  • CI runs on GitHub Actions

Generated with Claude Code

@tvinagre tvinagre force-pushed the tl/ENG-5578-integration-tests branch from 6725dc1 to 5f6eb60 Compare March 23, 2026 19:45
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 23, 2026

Breaking API Changes (Intentional)

Breaking API changes detected and declared in the PR title.
Ensure the minor version is bumped before merging (breaking changes on 0.x.x bump the minor).

semver-checks output
Checking fynd-core v0.49.1 -> v0.49.1 (no change; assume minor)
     Checked [   0.548s] 196 checks: 196 pass, 49 skip
     Summary no semver update required
    Finished [   0.757s] fynd-core
    Checking fynd-rpc v0.49.1 -> v0.49.1 (no change; assume minor)
     Checked [   0.080s] 196 checks: 195 pass, 1 fail, 0 warn, 49 skip

--- failure function_missing: pub fn removed or renamed ---

Description:
A publicly-visible function cannot be imported by its prior path. A `pub use` may have been removed, or the function itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/function_missing.ron

Failed in:
  function fynd_rpc::builder::parse_chain, previously in file fynd-rpc/src/builder.rs:354

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [   0.133s] fynd-rpc
    Checking fynd-rpc-types v0.49.1 -> v0.49.1 (no change; assume minor)
     Checked [   0.131s] 196 checks: 196 pass, 49 skip
     Summary no semver update required
    Finished [   0.226s] fynd-rpc-types
    Checking fynd-client v0.49.1 -> v0.49.1 (no change; assume minor)
     Checked [   0.154s] 196 checks: 196 pass, 49 skip
     Summary no semver update required
    Finished [   0.301s] fynd-client

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.

Cooool! And then if this fails? Can we make it alert us on slack? I'm scared it might silently fail and never be noticed/fixed.

Copy link
Copy Markdown
Collaborator Author

@tvinagre tvinagre Mar 24, 2026

Choose a reason for hiding this comment

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

Yes - good point. Will do that as the next step!

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.

What is the motivation to run this periodically? 🤔 To make sure that Tycho's output is not weird? If yes, then we should support this for all chains we support 😕

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.

and this can give a lot of warnings if the price for tokens are just "normally" moving.. 😕

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@dianacarvalho1 - I believe it's a misunderstanding. This would fail only if Tycho changes its output format OR it is down.
We use the recording tool to regenerate the recordings, targets and run Fynd with the recorded data. This would also error if we are having non-deterministic values (which is most likely a bug since the data is the same).

Comment thread fixtures/integration/README.md Outdated
Comment thread fixtures/integration/README.md Outdated
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.

I think this readme is misplaced. It should be split into 2 and be in fynd-core/src/recording and fynd-core/test/integration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess some of this information should also be put into the knowledge documents for LLMs?

Comment thread fixtures/integration/README.md Outdated
Comment thread fynd-core/src/feed/mod.rs Outdated
Comment on lines +15 to +16
pub(crate) struct TychoFeedConfig {
pub struct TychoFeedConfig {
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.

Is it needed outside of the crate? I'l scared of @zizou0x shouting at us for making something pub (loooool)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤣 - yes I launched a subagent only for that

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I made this private recently, why does it have to be public to add a test?

Comment thread fynd-core/src/types/constants.rs Outdated

/// Error returned when a chain name string cannot be parsed.
#[derive(Debug, Clone, thiserror::Error)]
#[error("unsupported chain '{0}'. Try values like 'ethereum', 'base', 'unichain'")]
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.

Would prefer we not list the chains here as this easily becomes outdated

Comment on lines +16 to +18
/// Derived data metrics should exactly match the golden baseline.
/// Since replay is deterministic (same recording → same derived data),
/// any deviation indicates a real bug, not expected variance.
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.

Really? I would say a positive deviation is allowed. What about if there's a tycho-simulation bug that we fix. Suddenly we get more successful spot prices compared to the latest golden baseline - this is a good thing but would fail the check?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Since replay is deterministic
I can rephrase this but this stands for "same recording, same code" should return the same result

this is a good thing but would fail the check?
Yeah the flow would be:

  1. dev would have a baseline to compare and will be very transparent about the improvements (wouldn't have to benchmark or do any manual testing).
  2. If they look good, dev will have to update the baseline - new numbers will be easily spottable on the PR review for the reviewer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Positive deviation can also indicate a nasty bug promising us 20 BTC for 1 ETH like the curve situation no?

Comment on lines +139 to +143
assert!(
regressions.is_empty(),
"quality regressions (>1% degradation):\n{}",
regressions.join("\n")
);
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.

Oh nice! So it was just the doc that was misleading... for solution quality it is a gte check with a 1% degradation allowance. Cool cool.

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.

Maybe all these integration test stuff should be feature gated? Or collected into its own mod or something? I feel like a lot of the integration test specific stuff leaked into fynd-core etc and it should be more contained.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you run the audit skill on these changes, por favor?

Comment thread tools/record-market/src/recorder.rs
Copy link
Copy Markdown
Contributor

@kayibal kayibal left a comment

Choose a reason for hiding this comment

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

Partial review for now. Mostly concerned about the newly exposed api surface from this PR. I think a lot of this API would be better suited to be placed within tycho-simulation if exposed publically.

Comment thread tools/fynd-swap-cli/src/main.rs Outdated
Comment on lines +34 to +36
builder::FyndRPCBuilder,
config::WorkerPoolsConfig,
parse_chain,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why did we move this?

Comment thread tools/record-market/Cargo.toml Outdated
tycho-simulation.workspace = true
tycho-execution.workspace = true
tokio = { workspace = true, features = ["full"] }
clap = { version = "4", features = ["derive"] }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

surprised we can't take it from the workspace

Comment thread tools/record-market/src/recorder.rs Outdated
.expect("time went backwards")
.as_secs(),
fynd_version: env!("CARGO_PKG_VERSION").to_string(),
recording_duration_s: actual_duration,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why the _s is this supposed to mean seconds??

Comment thread tools/record-market/src/recorder.rs Outdated
.as_secs(),
fynd_version: env!("CARGO_PKG_VERSION").to_string(),
recording_duration_s: actual_duration,
num_updates: updates.len(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

kind of pointless to have this attribute...unless you plean reading only the metadata.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah - the goal was to be able to support reading the metadata without deserializing the whole updates array

Comment on lines +168 to +175
let gas_price_wei = match block_gas_price.pricing {
GasPrice::Legacy { gas_price } => gas_price,
// EIP-1559: use max_fee_per_gas as the upper bound
other => {
tracing::warn!(?other, "non-legacy gas price, falling back to 10 gwei");
num_bigint::BigUint::from(10_000_000_000u64)
}
};
Copy link
Copy Markdown
Contributor

@kayibal kayibal Mar 25, 2026

Choose a reason for hiding this comment

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

Looks hacky... comment is not true?

Comment thread fynd-core/src/recording/mod.rs Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This whole module, I feel should not be here, instead it can live directly in the tool? If exposed as a lib, I think it should be in tycho-simulation

Comment thread fixtures/integration/README.md Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess some of this information should also be put into the knowledge documents for LLMs?

Comment thread fynd-core/src/recording/golden.rs Outdated
Comment on lines +31 to +33
/// Expected output for a scenario.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GoldenOutput {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ExpectedOutput would be a way better name for this struct and you can probably extend this naming pattern up through to the module name.

Comment thread fynd-core/src/recording/golden.rs Outdated
let content = include_str!("../../../tools/benchmark/src/pairs.json");
let raw: serde_json::Value = serde_json::from_str(content).expect("failed to parse pairs.json");

let tokens: std::collections::HashMap<String, (Address, u32)> = raw["tokens"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

unhandled panics here all over the place. Since this is a public library function, that is unfortunately not acceptable. But I think we should consider moving as much as possible from here to the tool binary.

Comment thread fynd-core/src/recording/types.rs Outdated
Comment on lines +10 to +15
/// A serializable mirror of [`Update`].
///
/// `Update` itself is `#[derive(Debug, Clone)]` only. All its fields
/// implement `Serialize`/`Deserialize` individually (`Box<dyn ProtocolSim>`
/// via `#[typetag::serde]`), so this wrapper just adds the derives.
#[derive(Debug, Clone, Serialize, Deserialize)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It would be a lot better to fix this quickly in tycho-simulation

Copy link
Copy Markdown
Contributor

@tamaralipows tamaralipows left a comment

Choose a reason for hiding this comment

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

Thanks - some questions mostly for my understanding

Comment thread fixtures/integration/README.md Outdated
Comment on lines +16 to +18
/// Derived data metrics should exactly match the golden baseline.
/// Since replay is deterministic (same recording → same derived data),
/// any deviation indicates a real bug, not expected variance.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Positive deviation can also indicate a nasty bug promising us 20 BTC for 1 ETH like the curve situation no?


/// Quality: each pair's amount_out_net_gas should be within 1% of golden baseline.
#[tokio::test]
async fn test_quality_within_golden_baseline() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So it seems this is the most important test that we should be running in case of any code change? It took me a while to find this as an outsider - should we add this to some readme? It would be a lot easier to develop this way than to run every cargo test every time? Not sure where the best place to put this info is.

Comment thread tools/record-market/src/golden.rs Outdated
Comment on lines +51 to +53
fn default_min_hops() -> usize {
1
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it not be better to increase this for integration testing purposes? I feel a number of bugs happened thx to sequential swaps for example on consecutive vm protocols?

Copy link
Copy Markdown
Collaborator

@dianacarvalho1 dianacarvalho1 left a comment

Choose a reason for hiding this comment

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

Thank you @tvinagre ! I gave a quick review - there are already a lot of good suggestions (that I agree 👍🏼)!

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.

What is the motivation to run this periodically? 🤔 To make sure that Tycho's output is not weird? If yes, then we should support this for all chains we support 😕

Comment thread fixtures/integration/README.md Outdated
Comment on lines +82 to +86
- **VM-backed protocols filtered**: Protocol states that depend on EVM engine
state (e.g., UniswapV4) cannot be serialized and are dropped during
recording. Pools for these protocols are registered as components but have
no simulation state, so they cannot compute spot prices or be used for
routing.
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.

oohhh 😞 how difficult would it be to serialise the vm protocols? (I know that it isn't in scope of this PR!)

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.

and this can give a lot of warnings if the price for tokens are just "normally" moving.. 😕

@tvinagre tvinagre force-pushed the tl/ENG-5578-integration-tests branch from 5f6eb60 to 29cce24 Compare April 6, 2026 19:10
Comment thread fixtures/integration/README.md Outdated
- `market_recording.json.zst` — Zstd-compressed JSON recording of Tycho
protocol stream updates. Captured from live Tycho mainnet using the
`record-market` tool.
- `golden_outputs.json` — Expected quote outputs for a set of canonical
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

wrong, new file is expected_outputs.json

Comment thread fynd-core/src/solver.rs Outdated
pools: std::collections::HashMap<String, PoolConfig>,
gas_price_wei: Option<num_bigint::BigUint>,
) -> Result<Self, SolverBuildError> {
use tycho_simulation::tycho_ethereum::gas::{BlockGasPrice, GasPrice};
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These should be top-level imports since this is not feature-gated nor test-only imports.

Comment thread fynd-core/src/solver.rs Outdated
.await
.last_updated()
.map(|b| b.number())
.unwrap_or(0);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Should at least add a warning that if failed to extract block number. Same for gas price

Comment thread fynd-rpc/src/builder.rs
@@ -346,13 +342,3 @@
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Double check if this move + the reexport were necessary

Comment thread Cargo.toml Outdated
# Tycho
tycho-simulation = ">=0.254.0"
# TODO: revert to crates.io version once tycho-simulation PR #568 merges
tycho-simulation = { path = "/Users/thales/Environments/data_revenue/propeller_heads/tycho-simulation" }
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Important! Revert once PR is merged

tvinagre and others added 17 commits April 8, 2026 17:45
Introduce recording module in fynd-core with serializable wrappers
around Tycho Update messages for integration testing. Uses serde_json
(required by typetag) + zstd for compact storage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Write and read MarketRecording files using serde_json for typetag
compatibility and zstd compression. Roundtrip tested with both
empty recordings and recordings containing ProtocolSim trait objects.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address code quality review findings:
- Add doc comments to write_recording and read_recording
- Move tempfile to workspace dependencies for consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make handle_tycho_message pub for replay access. Re-export MarketEvent
and DerivedDataEvent for integration test access.
Test harness replays recorded Update messages through TychoFeed,
computes derived data, builds worker pools, and exposes a quote()
method for integration tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Store WorkerPool in TestHarness to prevent thread leaks
- Store ComputationManager JoinHandle for panic visibility
- Use QuoteStatus enum instead of String in GoldenOutput
- Remove premature include_str\! from load_test_scenarios
- Parse WETH address before acquiring read lock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLI tool that connects to Tycho, captures market state,
and generates golden outputs for integration testing.
Core recording and golden generation logic is stubbed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests verify all golden pairs return solutions, unknown tokens
produce errors, quality stays within 1% of baseline, and basic
invariants hold (positive net output, bounded hops, positive gas).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
P95 solve time must stay within 4x golden baseline or 200ms
absolute cap. No individual solve may exceed the absolute cap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Verifies all derived data fields are computed and coverage meets
thresholds: spot prices >= 95%, pool depths >= 90%, token gas
prices >= 80%.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Run BLESS_GOLDEN=1 cargo nextest run to regenerate golden_outputs.json
from the existing market recording after code changes that intentionally
affect solution quality.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Track *.json.zst files in fixtures/integration/ with Git LFS
to avoid bloating the repository with large market recordings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integration tests run on every PR using recorded market data.
Nightly canary connects to live Tycho to detect API drift and
real-world regressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace todo!() stubs with working implementations:
- recorder.rs: connect to Tycho, discover protocols, capture Update
  messages from ProtocolStreamBuilder for the configured duration
- golden.rs: replay recording through TychoFeed, compute derived data,
  build WorkerPoolRouter, run all pairs.json scenarios, capture outputs
- scenarios.rs: parse pairs.json token definitions and trading pairs
  with decimal-scaled amounts into TestScenario structs

Also: make register_exchanges pub for recorder access, add
tycho-execution/tokio-stream/num-bigint deps to record-market,
remove dead_code allows from harness and scenarios modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tested against tycho-beta.propellerheads.xyz mainnet. Fixes:

- Add protocol filter, TVL range, min_token_quality, and
  traded_n_days_ago CLI flags to control recording scope
- Use TLS by default (production Tycho requires it)
- Replace chain_id with chain name string in RecordingMetadata
- Add recording filter params to RecordingMetadata for reproducibility
- Fix TVL filter: with_tvl_range(min, min) not (min, 0.0)
- Fix broadcast channel error: keep a receiver alive during replay
  so handle_tycho_message's event broadcast doesn't fail
- Wait for spot_prices + pool_depths (not token_prices) in replay
  since token_prices requires a live gas_price feed
- Remove unused rpc_url from recorder (not needed for Tycho stream)
- Add .gitattributes comment explaining LFS tracking
- Increase derived data timeout to 120s for larger recordings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move worker pool construction before MarketUpdated event so workers
  receive DerivedDataEvent broadcasts (fixes all-NotReady race condition)
- Filter non-serializable VM-backed states in RecordedUpdate conversion
  (fixes "not supported due vm state deps" serialization error)
- Inject synthetic gas price (10 gwei) in replay mode so token_prices
  can compute (fixes MissingDependency("gas_price"))
- Increase algorithm timeout to 2s and workers to 4 for golden generation
- Wait for token_prices (not just pool_depths) before running scenarios
- Add initial market recording fixture and golden outputs (41/44 passing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ests

- Move parse_chain to fynd-core::types::constants for reuse (item 1)
- Add gas_price_gwei to RecordingMetadata + --rpc-url CLI option (item 3)
- Fix block_number: extract from last update instead of hardcoded 0 (item 4)
- Replace find_weth_address with native_token(&Chain::Ethereum) (item 6)
- Load worker pool config from worker_pools.toml (item 7)
- Remove --chain CLI option, hardcode Ethereum (item 8)
- Deduplicate golden types: shared GoldenFile/TestScenario in fynd-core (item 9)
- Fix market_tx dropped causing workers to exit (integration test bug)
- Build separate pools from toml like production (golden.rs)
- Use min_responses(0) in golden generation (match production)
- Adjust test thresholds for replay non-determinism
- All 11 integration tests pass (41/44 scenarios successful)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tvinagre and others added 14 commits April 8, 2026 17:45
- Store gas price as raw wei string instead of lossy gwei float (item 1)
- Remove parse_chain wrapper from builder.rs, use fynd_core directly (item 2)
- Add comment explaining serde_json::to_value filter mechanism (item 3)
- Tighten spot_prices threshold to 95% by excluding stateless pools (item 4)
- Switch harness to multi-pool matching production config (item 5)
- Remove scenarios.rs re-export file, import from fynd_core directly (item 6)
- Revert quality threshold to 1% (item 7)
- Remove test_bless_golden_outputs duplicate behavior (item 8)
- Derive timing test cap from worker_pools.toml max timeout (item 9)
- Add fixtures/integration/README.md documenting the test setup (item 10)

All 10 integration tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rtions

Store spot_price_pools, pool_depth_pools, and token_prices counts in
GoldenMetadata.derived_data during golden generation. Integration tests
assert exact equality against these values since replay is deterministic.

Replaces 3 threshold-based coverage tests with a single
test_derived_data_matches_golden that also verifies pool/token counts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Re-expose TychoFeed, TychoFeedConfig, DataFeedError as pub (needed by
  recording tool and integration tests for replay)
- Re-export parse_chain from fynd_rpc for tools that don't depend on
  fynd-core directly (fynd-swap-cli, fynd-benchmark)
- Add tools/record-market to workspace members alongside tools/fynd-swap-cli
- Regenerate Cargo.lock after rebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve conflicts in .gitignore, Cargo.toml, lib.rs, feed/mod.rs,
  derived/mod.rs, builder.rs, src/main.rs, fynd-swap-cli
- Add missing doc comments required by main's #[warn(missing_docs)]
- Re-expose TychoFeed/TychoFeedConfig/DataFeedError as pub for replay
- Adapt to main's renames (BlacklistConfig -> BlocklistConfig)
- Adapt to main's worker_pools.toml (bellman_ford_2_hops)
- Regenerate golden fixtures from fresh recording

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add fynd-test-fixtures crate with shared types (ExpectedOutput,
  MarketRecording, TestScenario) — no test code in fynd-core lib
- Add Solver::from_recording() factory method — encapsulates replay
  pipeline, keeps TychoFeed/TychoFeedConfig as pub(crate)
- Delete fynd-core/src/recording/ module entirely
- Remove zstd from fynd-core dependencies
- Rename GoldenOutput -> ExpectedOutput per reviewer feedback
- Move fixtures to fynd-core/tests/fixtures/ (closer to tests)
- Tool reads back recording before generating expected outputs to
  ensure golden matches deserialized data (VM states filtered)
- load_test_scenarios() returns Result (no panics in library code)
- parse_chain error no longer lists specific chain names
- Split READMEs: tools/record-market/ + fynd-core/tests/integration/
- Use local tycho-simulation path dep (pending PR #568 merge)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 8 integration tests pass consistently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…adme

- Move BlockGasPrice/GasPrice/MarketEvent imports to top-level (not
  feature-gated or test-only)
- Add tracing::warn when block number or gas price fall back to defaults
  in from_recording
- Fix README reference: golden_outputs.json → expected_outputs.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The local filesystem path breaks builds for anyone else. Point to the
upstream PR branch until PR #568 merges and a crates.io release follows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sion

Architecture:
- Gate Solver::from_recording and SolverBuildError::Replay behind
  cfg(feature = "test-utils") so test infrastructure stays off the
  public API surface
- Revert 3 unnecessary visibility escalations (MarketEvent re-export,
  handle_tycho_message pub, DerivedDataEvent re-export)
- Remove unused anyhow dep from fynd-core

Canary workflow fixes:
- Use --output-dir (not --output) matching the actual CLI flag
- Write directly to fynd-core/tests/fixtures/ (where tests read)
- Add --features test-utils to nextest invocations
- Add failure notification step

Test improvements:
- Use BigUint arithmetic for quality comparison instead of lossy f64
- Add RUSTFLAGS="-D warnings" to integration test CI job
- Add publish = false to record-market Cargo.toml

Cleanup:
- Remove dead _worker_pools_hash computation in golden.rs
- Remove dead expected_file_path() function
- Log warning on gas price parse failure instead of silent None

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…infra

- Remove stale fixtures/integration/ duplicate (686KB binary in git objects)
- Pin all CI actions to commit SHAs in new integration_tests and canary jobs
- Hoist sha2 to workspace dependencies
- Add schema_version field to RecordingMetadata for format versioning
- Deduplicate PoolsFile into parse_pools_toml() in test-fixtures
- Warn on broadcast failure in from_recording instead of silent drop
- Guard f64-to-u128 cast in scenario loader with finite/non-negative check
- Tighten P95 timing threshold from 4x to 3x

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the duplicate fixtures/integration/ directory (tests read from
fynd-core/tests/fixtures/). Rename golden.rs to expected.rs and replace
all "golden" references with "expected" for consistent naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tvinagre tvinagre force-pushed the tl/ENG-5578-integration-tests branch from 29cce24 to d84433d Compare April 9, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants