Skip to content

feat(backend): improve reliability and test coverage#1285

Merged
Yunusabdul38 merged 2 commits into
Web3Novalabs:mainfrom
software321dev:feat/backend-improvements-1172-1173-1174-1175
Jun 28, 2026
Merged

feat(backend): improve reliability and test coverage#1285
Yunusabdul38 merged 2 commits into
Web3Novalabs:mainfrom
software321dev:feat/backend-improvements-1172-1173-1174-1175

Conversation

@software321dev

Copy link
Copy Markdown
Contributor

feat(backend): clean up unused imports, CORS whitelist tests, configurable DB connect timeout, and Redis cache-miss unit tests

Summary

This PR resolves four backend improvement issues targeting code quality, observability, and test coverage in the Axum-based Rust backend:

Issue Title
#1172 Clean up unused imports in server.rs
#1173 Implement CORS whitelist checks from config
#1174 Configurable connect delay for Postgres database pool
#1175 Add unit tests for Redis cache cache-miss scenarios

Changes

Issue #1172 — Clean up unused imports in server.rs

File: backend/src/server.rs

server.rs previously imported tokio::time::Duration under the alias TokioDuration while also importing std::time::Duration. This created redundant, potentially confusing dual Duration types in the same scope. The fix removes the Duration as TokioDuration alias from the tokio import and updates the single usage site to use the already-imported std::time::Duration directly:

-use tokio::time::{sleep, Duration as TokioDuration};
+use tokio::time::sleep;
-sleep(TokioDuration::from_secs(backoff_duration)).await;
+sleep(Duration::from_secs(backoff_duration)).await;

This reduces cognitive overhead for contributors reading the file — there is now only one Duration type in scope.


Issue #1173 — CORS whitelist checks from config

File: backend/src/server.rs (new #[cfg(test)] mod tests block)

The build_cors function already reads config.cors_allowed_origins to build the CorsLayer, enforcing the whitelist set at startup. However, there were no unit tests exercising this path. This PR adds a dedicated tests module in server.rs with 6 tests covering:

  • build_cors_accepts_valid_https_origin — valid https:// origin is accepted without panic
  • build_cors_default_origins_are_all_valid_header_values — all 3 default origins parse into valid HeaderValues (none silently dropped)
  • build_cors_accepts_origin_with_porthttp://localhost:5173 parses correctly
  • build_cors_accepts_multiple_origins — multiple simultaneous origins all accepted
  • build_cors_with_empty_origins_does_not_panic — empty list produces a restrictive layer without crashing
  • build_cors_uses_config_origins_not_hardcoded_list — confirms build_cors is parametric over the config (reads from struct, not a hardcoded list)

These tests run entirely without network access and complete in milliseconds.


Issue #1174 — Configurable connect delay for Postgres database pool

Files: backend/src/config.rs, backend/src/db.rs, backend/.env.example

Problem

The Postgres pool had acquire_timeout (max wait for a slot in an already-open pool) but no separate connect_timeout — the per-connection TCP/TLS handshake timeout. In slow network environments or when Postgres is behind a load balancer, individual connections could hang for the full OS TCP timeout (several minutes) before failing, causing cascading startup delays.

Implementation

  • Config: Added db_connect_timeout_secs: u64 field (default 10) loaded from PREDIFI_DB_CONNECT_TIMEOUT_SECS env var.
  • db.rs: Wires config.db_connect_timeout_secs into PgPoolOptions::connect_timeout() so each individual connection is bounded.
  • .env.example: Documents the new variable with a clear comment distinguishing it from PREDIFI_DB_ACQUIRE_TIMEOUT_SECS.
PgPoolOptions::new()
    .max_connections(config.db_max_connections)
    .min_connections(config.db_min_connections)
    .acquire_timeout(Duration::from_secs(config.db_acquire_timeout_secs))
    .connect_timeout(Duration::from_secs(config.db_connect_timeout_secs))  // NEW
    .connect(&config.database_url)

Tests added in db.rs

  • backoff_delay_with_zero_base_is_zero — zero base delay always yields zero
  • backoff_delay_saturates_at_max — high attempt counts are capped
  • retry_with_backoff_treats_zero_max_as_onemax_attempts = 0 clamped to 1
  • retry_with_backoff_succeeds_on_first_attempt — fast path: success on attempt 1 skips retries
  • config_connect_timeout_is_independent_from_acquire_timeout — the two timeout fields are independently set and non-zero

Issue #1175 — Unit tests for Redis cache cache-miss scenarios

File: backend/src/redis_cache.rs

The existing test suite only verified the disabled-cache no-op path at a surface level. This PR adds comprehensive cache-miss tests across three categories:

Disabled-cache / cache-miss tests

Test What it verifies
cache_miss_on_disabled_cache_returns_none_for_any_key GET on pools, pool-details, and user-predictions keys all return None
cache_miss_after_set_on_disabled_cache SET then GET still returns None (no backing store)
cache_miss_delete_on_disabled_cache_is_noop delete and delete_pattern on disabled cache don't panic
disabled_cache_is_not_available is_available() returns false
disabled_cache_ping_returns_false ping() returns false
cache_miss_is_none_not_empty_collection Miss returns None, not Some(vec![])
cache_miss_after_ttl_simulated_via_disabled_cache Even within TTL window a disabled cache always misses

Cache-key uniqueness tests

Test What it verifies
pools_cache_keys_differ_by_offset Different pagination offsets produce distinct keys
pool_details_keys_differ_by_id Different pool IDs produce distinct keys
user_predictions_keys_differ_by_address Different user addresses produce distinct keys
cache_key_generation_is_deterministic Same input always yields same key

All tests use RedisCache::disabled()no live Redis instance required, making them safe for CI environments.


How to Verify

cd backend
cargo test

All new tests are unit tests that run without any external services (no Postgres, no Redis).

To verify the configurable connect timeout works end-to-end:

PREDIFI_DB_CONNECT_TIMEOUT_SECS=2 cargo run

With an unreachable Postgres host, the connection attempt will now fail after ~2 seconds per try rather than waiting for the OS TCP timeout.


Closes

Closes #1172
Closes #1173
Closes #1174
Closes #1175

@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

@rhoggs-bot-test-account is attempting to deploy a commit to the shola's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@software321dev Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Yunusabdul38 Yunusabdul38 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.

LGTM
Thanks for your contributon

@Yunusabdul38 Yunusabdul38 merged commit bb710a0 into Web3Novalabs:main Jun 28, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants