Add integration and unit tests for monitoring JSON API endpoints#373
Add integration and unit tests for monitoring JSON API endpoints#373gimballock wants to merge 1 commit into
Conversation
85a3f7e to
f7f95d2
Compare
f7f95d2 to
f3c2e96
Compare
Shourya742
left a comment
There was a problem hiding this comment.
Shouldn't monitoring module have abstractions for most of these?
f3c2e96 to
1f12145
Compare
|
I think the test failure here is the target of PR #338, once we rebase off of that this failure should go away i think. |
Shourya742
left a comment
There was a problem hiding this comment.
I still dont see any changes requested. Now, we have some random files in the PR
d7dfb76 to
65dd528
Compare
My bad, all those extra files are removed now. |
1f5ce90 to
6ecedf7
Compare
|
Rebased onto main and addressed all review feedback. Summary of changes in the current commit: All review feedback addressed:
Additional cleanup done during rebase:
@Shourya742 if you could take a look when you have a chance |
|
Note:when running the monitoring integration tests sequentially ( |
6ecedf7 to
cf90755
Compare
|
Thanks for investigating. I believe this is pre-existing and unrelated to this PR — opened #430 to track it. Looking at the code, This PR's tests use isolated ports via |
cf90755 to
d71e1a3
Compare
|
I rebased and tried to account for all the changes since last update now that #338 is merged |
d71e1a3 to
f44cd52
Compare
|
clean rebase w/ latest |
… API test, unpack race fix Originally the third commit in this PR's series, now amended to fold in review-feedback fixes from stratum-mining#373. Coverage expansion (from the original commit): * **JDC API endpoints test.** Adds `jdc_api_endpoints_with_miner`, parallel to the existing Pool and tProxy with-miner tests. JDC sits between pool and tProxy: it is an SV2 client to the pool (so `server` is populated on /api/v1/global) and an SV2 server to the tProxy (so `sv2_clients` is populated). JDC has no SV1 surface, so /api/v1/sv1/clients must 404. Exercises root, /api/v1/global, /api/v1/server, /api/v1/server/channels, /api/v1/clients, /api/v1/clients/{id}, /api/v1/clients/{id}/channels and the SV1 404. * **shares_rejected field-shape regression guard.** Adds inline JSON asserts to the tProxy and JDC with-miner tests verifying that the upstream-channel detail under /api/v1/server/channels exposes both `shares_rejected` (number) and `shares_rejected_by_reason` (object). This guards against rename or type regressions of the kind PR stratum-mining#468 surfaced. The guard intentionally lives only on roles whose channels use the server-side `ServerExtendedChannelInfo` struct (tProxy and JDC); the pool's downstream-client channels use `ExtendedChannelInfo`/ `StandardChannelInfo`, which by design do not carry these fields. Address review feedback — reuse production types instead of mirrors: Production-side changes (stratum-apps): * Make the JSON response wrapper structs in `monitoring::http_server` (`HealthResponse`, `ErrorResponse`, `ServerResponse`, `ServerChannelsResponse`, `Sv2ClientsResponse`, `Sv2ClientResponse`, `Sv2ClientChannelsResponse`, `Sv1ClientsResponse`) `pub` and derive `Deserialize` + `Debug` so they can serve both as the wire-format layer in handlers and as the parse target in tests and downstream consumers. Re-export from `monitoring::mod`. Test-side changes: * `integration-tests/lib/prometheus_metrics_assertions.rs`: drop the `Api*` mirror types entirely. The typed `poll_until_*_gte` helpers now return the production types directly (`GlobalInfo`, `Sv2ClientsResponse`, `Sv1ClientsResponse`, `ServerResponse`). `assert_api_health` parses into `HealthResponse`. Delete unused `fetch_api_json` (callers use `fetch_api_typed::<T>` instead). * `integration-tests/tests/monitoring_integration.rs`: switch `fetch_api_typed` call sites to the production types (`Sv2ClientResponse`, `Sv2ClientChannelsResponse`, `Sv1ClientInfo`). The three root-endpoint tests (`/` is hand-rolled JSON in `handle_root` with no production struct) read `serde_json::Value` directly. * `stratum-apps/src/monitoring/http_server.rs`: drop the `*Body` shadow types from the test module and parse responses directly into the production response types. Clean up three stale `super::super::*` paths to bare names (artifacts from before the consolidation refactor) and align the `routes::*` URL helpers on `usize` (matching the production `client_id` type). Also restore the `///` doc comment on `assert_metric_gte` that was accidentally dropped while adding `#[track_caller]`. Unrelated fix kept in this commit because the new tests surfaced it: * `integration-tests/lib/utils.rs::tarball::unpack` was writing every tarball to a fixed `<destination>/temp.tar.gz`. When several tests start a pool/tProxy in parallel, both extractions land in the same shared `template-provider/` cache dir and truncate each other's tarball mid-extraction, manifesting as `tar: ...: truncated gzip input`. Switch to a process-unique path under `std::env::temp_dir()` with an `AtomicU64` nonce, and clean up the temp file even when extraction fails. The remaining redundant extraction (two threads both pass the "is bitcoin already extracted?" guard and both unpack) is benign — same tarball, same destination, idempotent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
f44cd52 to
f715d3f
Compare
… API test, unpack race fix Originally the third commit in this PR's series, now amended to fold in review-feedback fixes from stratum-mining#373. Coverage expansion (from the original commit): * **JDC API endpoints test.** Adds `jdc_api_endpoints_with_miner`, parallel to the existing Pool and tProxy with-miner tests. JDC sits between pool and tProxy: it is an SV2 client to the pool (so `server` is populated on /api/v1/global) and an SV2 server to the tProxy (so `sv2_clients` is populated). JDC has no SV1 surface, so /api/v1/sv1/clients must 404. Exercises root, /api/v1/global, /api/v1/server, /api/v1/server/channels, /api/v1/clients, /api/v1/clients/{id}, /api/v1/clients/{id}/channels and the SV1 404. * **shares_rejected field-shape regression guard.** Adds inline JSON asserts to the tProxy and JDC with-miner tests verifying that the upstream-channel detail under /api/v1/server/channels exposes both `shares_rejected` (number) and `shares_rejected_by_reason` (object). This guards against rename or type regressions of the kind PR stratum-mining#468 surfaced. The guard intentionally lives only on roles whose channels use the server-side `ServerExtendedChannelInfo` struct (tProxy and JDC); the pool's downstream-client channels use `ExtendedChannelInfo`/ `StandardChannelInfo`, which by design do not carry these fields. Address review feedback — reuse production types instead of mirrors: Production-side changes (stratum-apps): * Make the JSON response wrapper structs in `monitoring::http_server` (`HealthResponse`, `ErrorResponse`, `ServerResponse`, `ServerChannelsResponse`, `Sv2ClientsResponse`, `Sv2ClientResponse`, `Sv2ClientChannelsResponse`, `Sv1ClientsResponse`) `pub` and derive `Deserialize` + `Debug` so they can serve both as the wire-format layer in handlers and as the parse target in tests and downstream consumers. Re-export from `monitoring::mod`. Test-side changes: * `integration-tests/lib/prometheus_metrics_assertions.rs`: drop the `Api*` mirror types entirely. The typed `poll_until_*_gte` helpers now return the production types directly (`GlobalInfo`, `Sv2ClientsResponse`, `Sv1ClientsResponse`, `ServerResponse`). `assert_api_health` parses into `HealthResponse`. Delete unused `fetch_api_json` (callers use `fetch_api_typed::<T>` instead). * `integration-tests/tests/monitoring_integration.rs`: switch `fetch_api_typed` call sites to the production types (`Sv2ClientResponse`, `Sv2ClientChannelsResponse`, `Sv1ClientInfo`). The three root-endpoint tests (`/` is hand-rolled JSON in `handle_root` with no production struct) read `serde_json::Value` directly. * `stratum-apps/src/monitoring/http_server.rs`: drop the `*Body` shadow types from the test module and parse responses directly into the production response types. Clean up three stale `super::super::*` paths to bare names (artifacts from before the consolidation refactor) and align the `routes::*` URL helpers on `usize` (matching the production `client_id` type). Also restore the `///` doc comment on `assert_metric_gte` that was accidentally dropped while adding `#[track_caller]`. Unrelated fix kept in this commit because the new tests surfaced it: * `integration-tests/lib/utils.rs::tarball::unpack` was writing every tarball to a fixed `<destination>/temp.tar.gz`. When several tests start a pool/tProxy in parallel, both extractions land in the same shared `template-provider/` cache dir and truncate each other's tarball mid-extraction, manifesting as `tar: ...: truncated gzip input`. Switch to a process-unique path under `std::env::temp_dir()` with an `AtomicU64` nonce, and clean up the temp file even when extraction fails. The remaining redundant extraction (two threads both pass the "is bitcoin already extracted?" guard and both unpack) is benign — same tarball, same destination, idempotent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
f715d3f to
2b6d0be
Compare
|
@gimballock can you please reword/squash commits here? In both titles and descriptions we have some stale changes IMO. |
Adds integration and unit-test coverage for the monitoring HTTP JSON API and Prometheus surfaces of pool, tProxy, and JDC. Also exposes the existing response types in `stratum_apps::monitoring` as the canonical parse targets so tests don't reimplement them. Integration tests (`integration-tests/tests/monitoring_integration.rs`): * Topology-shaped tests rather than per-endpoint. Each test spins up its topology once and exercises every relevant endpoint: - `pool_api_endpoints_static` / `pool_api_endpoints_with_miner` - `tproxy_api_endpoints_static` / `tproxy_api_endpoints_with_miner` - `jdc_api_endpoints_with_miner` The JDC test in particular is interesting because JDC sits between pool and tProxy: it is an SV2 client to the pool (so `server` is populated on /api/v1/global) and an SV2 server to the tProxy (so `sv2_clients` is populated). JDC has no SV1 surface, so /api/v1/sv1/clients must 404. * Cross-validate JSON API and Prometheus. The two with-miner tests assert matching Prometheus counters via the `Metric::with_labels` selector, catching drift between the two surfaces. * `shares_rejected` field-shape regression guard. Inline JSON asserts on the tProxy and JDC tests verify that the upstream-channel detail under /api/v1/server/channels exposes both `shares_rejected` (number) and `shares_rejected_by_reason` (object). This guards against rename / type regressions of the kind PR stratum-mining#468 surfaced. The guard intentionally lives only on roles whose channels use `ServerExtendedChannelInfo` (tProxy and JDC); the pool's downstream-client channels use `ExtendedChannelInfo` / `StandardChannelInfo`, which by design do not carry these fields. Unit tests (`stratum-apps/src/monitoring/http_server.rs`): * Per-endpoint unit tests against `build_test_app` with mock data, exercising 200/404 paths, pagination edges, and the stale-channel-label cleanup behaviour. Test infrastructure (`integration-tests/lib/prometheus_metrics_assertions.rs`): * `fetch_api`, `fetch_api_typed::<T>`, `fetch_api_with_status` plus typed `poll_until_*_gte` helpers for `/api/v1/global`, `/api/v1/clients`, `/api/v1/server`, and `/api/v1/sv1/clients`. * `Metric::with_labels` selector for matching Prometheus exposition lines with order- and subset-tolerant label matching. * `assert_metric_*` / `assert_metric_not_present` / `assert_uptime` / `assert_api_health`, all `#[track_caller]` so panic locations point at the call site. Production-side changes (`stratum-apps`): * Make the JSON response wrapper structs in `monitoring::http_server` (`HealthResponse`, `ErrorResponse`, `ServerResponse`, `ServerChannelsResponse`, `Sv2ClientsResponse`, `Sv2ClientResponse`, `Sv2ClientChannelsResponse`, `Sv1ClientsResponse`) `pub` and derive `Deserialize` + `Debug` so they serve as both the wire-format layer in handlers and the parse target in tests and downstream consumers. Re-export from `monitoring::mod`. Tests deserialize directly into these production types rather than redeclaring shadow copies. The one exception is the `/` root endpoint, which is hand-rolled JSON in `handle_root` with no production struct; tests parse it as `serde_json::Value`.
2b6d0be to
94edcb3
Compare
|
@gimballock can you rebase this PR? Once you do that, I'll merge it. |
Closes #329
Exercise every JSON REST API endpoint against live SV2 topologies and strengthen unit-test coverage for edge cases.
Integration tests (monitoring_integration.rs):
Assertion helpers (prometheus_metrics_assertions.rs):
HTTP helper (utils.rs):
Unit tests (http_server.rs):
Dependencies: